The case for Sanity as your first CMS
Most CMS choices are made too early and regretted too late. Here's why we reach for Sanity on most projects and what makes it worth the setup cost compared to the alternatives.
5 min read
Every project has a default stack decision. Ours is Next.js with TypeScript. Here's the reasoning, the exceptions, and the cases where we'd choose something different.
Sahil Jadhav
Founder, Sero Studio
When a client comes to us with a new project, the first technical decision isn't which database to use or how to structure the API. It's the framework. And for most projects, we've made that decision before the first call ends. We're going to recommend Next.js.
This isn't laziness or tunnel vision. It's a deliberate default built from shipping real projects under real constraints.
A good default stack has a few properties. It handles the majority of cases well without requiring you to fight it. It has a healthy ecosystem of libraries, so you're not building plumbing when you should be building features. It has a deployment story that doesn't add operational overhead. And it has enough momentum that the client won't be maintaining a codebase built on something obscure in three years.
Next.js satisfies all of these. React is the dominant UI layer. The App Router handles routing, data fetching, and server rendering in a coherent model. Vercel deploys it in under a minute. TypeScript integration is first-class. The ecosystem is large enough that most problems have existing solutions.
The App Router model — Server Components by default, Client Components only when you need interactivity — maps well to how most web applications actually work. Most of what a web app does is fetch data and render it. Server Components do that with zero JavaScript shipped to the browser. Client Components handle the interactive bits. The split is explicit and auditable.
This matters for performance. A Next.js app with proper Server Component usage ships significantly less JavaScript than an equivalent SPA. For marketing sites and content-heavy applications, that translates directly to Core Web Vitals scores and search ranking.
// Server Component — runs on the server, zero client JS
// This is the default in Next.js App Router
async function ProjectList() {
const projects = await getProjects() // direct DB/API call
return <ul>{projects.map(p => <li key={p.id}>{p.title}</li>)}</ul>
}
// Client Component — only when you need it
'use client'
function FilterBar({ onFilter }: { onFilter: (f: string) => void }) {
const [active, setActive] = useState('All')
// ...
}Next.js is not always the right answer. Three cases where we'd reach for something different:
For a simple marketing site with no dynamic content and no plans to add any — a static site generator like Astro is leaner and ships less overhead. If SEO is the primary concern and the content is truly static, Astro is faster to build and produces smaller bundles.
For a real-time application where most of the UI is driven by live data — a SaaS tool with collaborative editing, for example — the App Router model creates friction. In that case we'd look at Remix, which has a more ergonomic data model for highly interactive apps, or a pure React SPA with a separate API layer.
For a mobile application, Next.js doesn't apply. React Native for cross-platform or Swift/Kotlin for native.
The App Router has a learning curve. The distinction between Server and Client Components is not intuitive coming from traditional React. Caching behaviour is powerful but has caught us out before when ISR behaves unexpectedly after a content update. The framework is opinionated in ways that occasionally require working around rather than with.
But none of those tradeoffs are deal breakers. They're the cost of a framework that handles the hard parts of web development — performance, routing, deployment, server rendering — at the level of the default rather than the exception.
More from the Studio
Most CMS choices are made too early and regretted too late. Here's why we reach for Sanity on most projects and what makes it worth the setup cost compared to the alternatives.
5 min read
Putting everything in a card is the fastest way to make a page feel like a grid of boxes. Here's how to use containment selectively to create visual rhythm rather than visual noise.
4 min read
Thoughts on building software, shipped occasionally.