next-saas-starter is a Next.js landing page template with the CMS wired in
⚡️ Free Next.js responsive landing page template for SaaS products made using JAMStack architecture.
At a glance
- What is it?
- next-saas-starter is a free MIT licensed Next.js template for SaaS marketing sites, with a pages-router application, an MDX blog, styled-components instead of a UI library, and Tina CMS wrapped around every package.json script so the same code path serves local editing and production. Its dependency pins are a generation behind current Next.js, and the project publishes no tagged releases.
- Who is it for?
- next-saas-starter fits a founder or a small team that needs a marketing site and a blog within a day and is comfortable deleting rather than configuring the parts it does not need, since the MDX blog, the newsletter form, the contact form and the dark mode all work out of the box and the admin routes work locally without a Tina Cloud account.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A pages-router application, not an App Router one
The template is built on Next.js with the pages directory at the top level, alongside components/, contexts/, hooks/, utils/, views/, posts/ and public/. The project description calls it a JAMStack architecture template for SaaS products, and the built-with list names Next.js for statically generated pages, styled-components, MDX and TypeScript.
The version pins tell you which generation of Next.js you are picking up. The dependencies put next at 12.1.0 with react and react-dom at 17.0.2, while the eslint config sits at eslint-config-next ^13.2.4 and the bundle analyzer at @next/bundle-analyzer ^13.3.1. So the runtime is a Next 12 application and the linting and tooling are a Next 13 generation. That mix is not necessarily broken, but it means the lint rules and the bundler plugin come from a newer major than the framework they are pointed at, and it means the app directory conventions that dominate current Next.js documentation are not what this codebase uses.
The TypeScript setup is conventional, with a tsconfig.json, a next-env.d.ts and a types.ts at the root for shared types, and the .eslintrc.json carries Next.js recommended settings with the imports sorting rule, plus a .prettierrc for formatting. The private flag is set in package.json and the version is 0.1.0, which is what you would expect from a template that is consumed by copying rather than by installing a package.
The other structural point is the env.ts file at the root. The getting started steps tell you to adjust the template to your needs and check out the env.ts file, so environment variables are validated in code at build time rather than read ad hoc from process.env in each component.
Tina CMS wraps every script, including the production build
This is the single most consequential design decision in the template, and it is not obvious from the feature list. Look at the scripts in package.json.
"scripts": {
"dev": "yarn tinacms server:start -c \"next dev\"",
"build": "yarn tinacms server:start -c \"next build\"",
"start": "yarn tinacms server:start -c \"next start\"",
"lint": "next lint"
}The dev, build and start commands are not Next.js commands. They are the Tina CLI starting Next.js as a child process through the -c flag. The consequence is that the CMS layer is in the path for building the site, not just for editing it. A build that fails because the Tina configuration or the Tina GraphQL layer misbehaves is a realistic outcome, and it is a failure mode that does not exist in a template where the CMS is bolted on only for local editing.
The upside is that the same content pipeline serves both modes, which is the usual reason a template makes this choice. The .tina/ directory at the top level holds the Tina configuration, and the dependency list includes tinacms at ^1.5.8 with the @tinacms/cli at ^0.60.0 in dev dependencies, so the CLI is a development-time tool while the runtime package ships with the app.
The README is also explicit that Tina is optional in production. Tina CMS integration is described as a local and optionally production CMS, and the optional setup step is to create a Tina Cloud account, a project, and fill in NEXT_PUBLIC_ORGANIZATION_NAME and NEXT_PUBLIC_TINA_CLIENT_ID. The editing model is described in a sentence that explains the whole arrangement: Tina's Content API authenticates directly with GitHub, so users do not need GitHub accounts, access is granted through the dashboard, and saved changes are committed to the configured branch in your repository. Editing a blog post is therefore a commit, and the branch is chosen by an environment variable.
The blog is MDX in the posts directory
The blog feature is described as a blog with MDX, and the repository has a posts/ directory at the top level, which tells you the content is files in your repository rather than rows in a database. The dependency list supports that reading: gray-matter for front matter parsing, reading-time for the estimated read time, prism-react-renderer for syntax highlighting, and date-fns for dates.
The local editing workflow is unusual and worth knowing before you start. The hint in the documentation says that to edit the blog pages you go to /admin and navigate to a blog page to edit it, and to exit editing mode you navigate to /admin/logout. So the admin route is served by the same Next.js application that serves the marketing pages, and it hands editing to the Tina client running in the browser against the local content layer. When you run the dev server, you get a content editor without a separate CMS account.
The front end carries a set of small libraries that tell you what the template tried to cover. There is swiper for carousels, @accessible/drawer for a drawer component, react-animate-height, use-clipboard-copy, @n8tb1t/use-scroll-position, use-resize-observer, react-hook-form for forms, react-mailchimp-subscribe for the newsletter form, @sendgrid/mail for sending email, react-schemaorg and schema-dts for structured data, react-share for sharing buttons, @svgr/webpack plus url-loader for SVG handling, and polished for colour manipulation.
The SEO claims are concrete in the dependency list rather than in the prose. The feature list promises meta tags, JSON-LD and Open Graph tags, and the code behind that is react-schemaorg, which generates schema.org structured data from TypeScript types checked by schema-dts. The Open Graph images come from next-api-og-image, credited in the acknowledgements as generating open graph images, and the dark mode comes from the Blazity fork nextjs-color-mode, credited as a non-flickering dark mode.
Environment variables decide what the template talks to
The.env.example file at the root is short and it is the fastest way to understand the integration points.
SENDGRID_API_KEY=
NEXT_PUBLIC_TINA_CLIENT_ID=
NEXT_PUBLIC_EDIT_BRANCH="master"
NEXT_PUBLIC_ORGANIZATION_NAME=
NEXT_PUBLIC_USE_LOCAL_CLIENT=""Only SENDGRID_API_KEY is a secret; the rest are public. SENDGRID_API_KEY is the credential for the Sendgrid integration, and the getting started steps say to set up your sendgrid API key and add it to environment variables in.env.local. The NEXT_PUBLIC_ prefix on the others means they are inlined into the client bundle, which is correct for the Tina client id and the organization name, and also means anything you put there is readable by anyone who views the page source.
The two that carry behaviour are worth calling out. NEXT_PUBLIC_EDIT_BRANCH is set to "master" by default, and it is the branch the editing commits land on, which is consistent with the default branch of the repository. The README warns to deploy to Vercel and not forget to add env variables, which is the usual failure of a one-click deploy: the site comes up and the email or CMS feature is silently inert because the build environment has no key.
NEXT_PUBLIC_USE_LOCAL_CLIENT is the switch between the two editing modes. Leaving it as an empty string, which is the default in the example, is what makes the local /admin editing work against the local content layer. The README describes Tina CMS integration as a local and optional production CMS, and this variable is where that choice is expressed in code.
Because the variables are consumed through the env.ts file rather than read directly, a missing or malformed value should fail at build time rather than at the moment a user submits the contact form.
Styled-components, and no UI library to learn
The feature list makes a point of what the template does not include: no UI library, just styled components, so you do not have to learn any new syntax. That is a design position rather than a shortcut, and it has consequences.
The dependency list confirms the approach, with styled-components at ^5.3.5 and no component framework in the tree. The theme system is described as dark mode and customizable themes, and the contexts/ and hooks/ directories at the top level are where that state lives. The acknowledgements credit a package called css-in-js-media as a convenient way of creating media queries, which appears in the dependencies as css-in-js-media ^2.0.1, and polished ^4.1.3 for the colour manipulation that a theme switch usually needs.
The upside of the no-library choice is that the visual result is entirely yours. There is no Material, no Chakra and no shadcn layer between you and the DOM, so a landing page can look like anything and the bundle does not carry a component kit you only use three components of. The downside is that the template ships fewer ready-made pieces than a starter built on a kit, so a page that is not in the template has to be built from scratch in the same system.
The Web Vitals claim also ties back to this. The feature list says the template is optimized for Web Vitals, and the README claims great SEO metrics and Green WebVitals. Static generation, no UI library, styled-components, and a small dependency set are consistent with that goal, although the README does not publish any measurement, so the claim is a design intent rather than a documented result.
One click deploy, static output, and no tagged releases
Deployment is treated as a first class path. The project provides a Vercel deployment button that points at a new project created from the repository, and a Netlify deploy button pointing at app.netlify.com, both described as free. The feature list calls it one click deployment with Vercel or any other serverless deployment environment.
The pages are statically generated, and the combination of pages/ with a static-friendly content directory means a marketing site can be served as static HTML with the client bundle doing the interactive parts. The blog content is committed to the repository, which is what makes the Tina editing model work: an editor saves, Tina commits to the branch, and a build produces the new page.
The maintenance picture is where a template has to be judged on the pin versions rather than on the last commit. The repository has no GitHub releases, and the package.json version is 0.1.0, so there is no version to pin a dependency on. The last push to master was on 2026-10-13, so the branch is being worked on, and the presence of renovate.json indicates that dependency updates are handled by automation rather than by hand. What that does not tell you is whether next 12.1.0 and react 17.0.2 are what you want to run, and those two pins are the practical constraint on adoption.
The answer to that is usually to upgrade deliberately. The template gives you a working application rather than a framework, so moving next forward is a dependency bump and a look at the pages directory conventions, not a rewrite. The README does not document an upgrade path, so treat that work as yours.
What a starter cannot decide for you
A landing page template saves you a day, and it also inherits every decision its author made about copy, structure, tone and layout. Nothing in the template lets you change the messaging strategy, because the messaging is the code. The views/ directory holds the page sections, and rewriting them is the work the template was supposed to save you from.
The second limit is the scope. What you get is a marketing site and a blog. There is no authentication, no user model, no database, no billing, and no application logic beyond the contact form, the newsletter subscription and the CMS editing surface. A template described as a landing page for a SaaS product is exactly that, and a team that reads it as an application scaffold will find the gap on day two.
The third limit is the coupling to two services. Sendgrid and Mailchimp are wired in with real library dependencies and real environment variables, and Tina Cloud is optional but supported. That is normal for a starter, but it means deciding how much of the template to keep is also deciding how many third party accounts you end up managing. A team that wants no external dependency can delete the sendgrid and mailchimp code paths, but they are integrated at the component level rather than behind a service layer, so removal is not one file.
The fourth limit is testing and CI. The repository has no test directory and no test script in package.json, and the scripts are limited to dev, build, start and lint..github/ is present, so some automation exists, but the template does not give you a test harness to build on.
Editorial conclusion
next-saas-starter fits a founder or a small team that needs a marketing site and a blog within a day and is comfortable deleting rather than configuring the parts it does not need, since the MDX blog, the newsletter form, the contact form and the dark mode all work out of the box and the admin routes work locally without a Tina Cloud account. It does not fit a team that wants the current Next.js App Router, since the project pins next to 12.1.0 and react to 17.0.2 with a pages/ directory at the top level. Before adopting it, run yarn build on your own machine, because the build script is wrapped in tinacms server:start, and pin a commit rather than a release, since the repository has no GitHub releases and the only published version is 0.1.0 in package.json.
Frequently asked questions
How do I run next-saas-starter locally?
The getting started steps have you use the template, add your sendgrid API key to environment variables in .env.local, adjust the template and check the env.ts file, then run yarn dev for the dev mode, yarn build to build the app and yarn start to run the production mode. The blog is edited at /admin in the browser and you exit editing mode at /admin/logout.
Which Next.js version does next-saas-starter use?
The package.json pins next to 12.1.0 with react and react-dom at 17.0.2, and the project uses the pages/ directory rather than the app directory. The linting and analysis tooling sits a major ahead at eslint-config-next ^13.2.4 and @next/bundle-analyzer ^13.3.1, so the runtime and the tooling are not on the same generation.
Do I need a Tina CMS or Tina Cloud account to edit blog posts?
Not for local editing. The blog is edited in the browser at /admin against the local content layer, and the optional setup step is to create a Tina Cloud account and project and fill in NEXT_PUBLIC_ORGANIZATION_NAME and NEXT_PUBLIC_TINA_CLIENT_ID for production editing. In production, Tina's Content API authenticates directly with GitHub and saved edits are committed to the configured branch.
What environment variables does next-saas-starter need?
The .env.example lists SENDGRID_API_KEY, NEXT_PUBLIC_TINA_CLIENT_ID, NEXT_PUBLIC_EDIT_BRANCH, NEXT_PUBLIC_ORGANIZATION_NAME and NEXT_PUBLIC_USE_LOCAL_CLIENT. The Sendgrid key is the only secret, and the README warns to add the environment variables when deploying to Vercel, since a one-click deploy does not carry them over.
Is next-saas-starter free to use and what license is it under?
Yes, the project is released under the MIT license with a LICENSE file at the root of the repository, and the README describes it as a free Next.js marketing website template for SaaS startups. The repository has no GitHub releases, so the package.json version of 0.1.0 is the only version identifier published.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/blazity-next-saas-starter)Was this useful?