Library / SDK
vercel/next-forge avatar
vercel/next-forge

next-forge names its vendors and ships a one-file CLI

Production-grade Turborepo template for Next.js apps.

7,772 stars734 forksTypeScriptMIT

At a glance

What is it?
Vercel's MIT licensed Turborepo template for Next.js applications, built as six independently deployable apps over eighteen shared packages, many of them wired to a named service. The published npm package is not a library: it is a single file whose job is scaffolding your copy of the monorepo.
Who is it for?
Treat next-forge as a starting point you will diverge from, not a dependency. The vendor names in the package list are the coupling to plan for, and the overwrite behaviour in the design-system update script is the detail that bites first if you edit those components in place.
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 169 days 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 November 13, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • vercel/next-forge7,772 ★ · +106
Star history
Repository2026-09-222026-11-13
vercel/next-forge7.7k7.8k

106 Stars in the last 52 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

The docs want Node 20 and the manifest allows 18

The prerequisites section lists Node.js 20 or newer, Bun or npm/yarn/pnpm, and the Stripe CLI for local webhook testing. The root manifest declares engines.node as greater than or equal to 18.

That is a small inconsistency, and it matters more than it looks, because the manifest field is what tooling actually reads. A CI configuration that trusts engines will happily install on Node 18 and then fail somewhere inside the app rather than at the version check. Treat 20 as the real floor and pin it explicitly in your project rather than relying on either signal.

The package manager is pinned as well: packageManager is set to bun 1.3.10, and the lockfile is bun.lock. The docs accept npm, yarn or pnpm as alternatives to Bun, but the repository's own dependency updates are driven through bunx.

The published package is one file and one command

What npm receives from this repository is not a library. The bin map points a single executable named next-forge at dist/index.js, and the files array contains exactly that path, so the tarball ships one JavaScript file. The runtime dependencies are correspondingly small: @clack/prompts for interactive prompts, commander for argument parsing, and nypm for package manager detection.

Publishing is configured with provenance enabled and public access, which means the release carries an attestation linking the tarball to the commit that produced it. Given that the package creates a project rather than running inside one, that matters more than usual: you are executing code that then becomes the foundation of your repository.

So the whole product is the init command:

sh
npx next-forge@latest init

Everything after that point is your code, which is why the documentation spends its length on setup guides and migration guides rather than on API reference.

Six apps, two fixed ports, independent deployment

The monorepo layout is fixed in the readme and worth memorising before you start moving things. apps/ holds the deployable applications: web, the marketing site on port 3001, and app, the main application on port 3000, then api, docs, email and storybook. packages/ holds the shared code, with design-system, database and auth named as the examples.

The stack behind each app is specified: the marketing site is Tailwind CSS with TWBlocks, the documentation site is Mintlify, email templates are React Email, and the API is a RESTful server with health checks and monitoring. Live demos exist for the web, app, Storybook and API surfaces, including a health check endpoint for the API.

The rule stated underneath the tree is the one to hold on to: each app is self-contained and independently deployable, and packages are shared across apps for consistency and maintainability. That is what makes six apps rather than one large app, and it is also what makes a change to a shared package a cross-application change.

Sixteen packages, and every one of them names a service

The package list is where the opinion in this template lives. Authentication is Clerk. Payments, described as subscription management, is Stripe. Transactional email is Resend. Analytics is split between Google Analytics for web and Posthog for product. Observability combines Sentry error tracking, logging, and BetterStack for uptime monitoring. Security covers Arcjet application security, rate limiting and secure headers.

The rest are capability packages that name fewer or no vendors: a type-safe ORM with migrations for the database, a design system with dark mode, a CMS for blogs and documentation, SEO with metadata, sitemaps and JSON-LD, AI integration utilities, inbound and outbound webhooks, real-time collaboration with avatars and live cursors, feature flags, cron, storage, internationalization and in-app notifications.

Every third-party commitment is therefore visible in a list you can read in one pass, which is a better position than discovering them later.

bump-ui regenerates the design system and overwrites your edits

Two scripts move dependencies forward and one of them has a sharp edge. bump-deps runs npm-check-updates with the deep flag, updates, and then installs, which is the ordinary maintenance path for transitive version drift.

The other is bump-ui:

bash
bunx shadcn@latest add --all --overwrite -c packages/design-system

The overwrite flag re-adds every component into packages/design-system, replacing what is there. That is the intended workflow when you want the design system back in sync with upstream shadcn, and it is also why local modifications to those components have to live somewhere other than the generated files. The readme does not call this out, so it is worth knowing before your first dependency bump.

Formatting and linting are handled by ultracite, with check and fix as separate scripts, and biome.jsonc sits at the root as the configuration.

Database work is three scripts pointed at one package

Migrations are confined to packages/database, and the scripts spell out the difference between development and deployment use. migrate runs prisma format, then prisma generate, then prisma migrate dev. migrate:deploy runs generate followed by migrate deploy, with no format step. db:push runs format, generate and db push instead, which skips the migration files entirely.

That is three different behaviours behind three names, and the deploy variant is the one that belongs in a release pipeline. db:push is the one to be careful with, because it reconciles the schema without recording a migration, which is convenient locally and a bad idea anywhere with history.

For everything else the repo delegates to Turborepo: build, dev, test, analyze and translate all pass through turbo, and boundaries runs Turborepo's own dependency boundary check across the workspace.

v6.0.0 through v6.0.2 shipped in a week, then the branch went quiet

The three most recent releases are unusually compressed. v6.0.0 was published on 13 March 2026, v6.0.1 on 16 March, and v6.0.2 on 20 March. The manifest is at 6.0.2, matching the newest tag.

After that comes a gap. The last push to main is dated 28 May 2026, so the branch has not moved in the five months since, and no release has been cut in roughly seven. That is the state to weigh when you decide whether to adopt a version: the 6.0 line arrived as a coordinated set of changes and then stopped, which is fine if you are content with what shipped and worth asking about if you need newer dependencies resolved.

The repository does keep a CHANGELOG.md, so the sequencing within a release series is documented even where the cadence between series is not.

Release automation is .autorc plus a publish script

Two files describe how this repository cuts a release. The first is .autorc at the root, which is configuration for the automated release tooling, and the dev dependencies include @auto-it/first-time-contributor, which is the plugin that handles attributing a merged pull request to its first-time contributor.

The second is the release script in the manifest, which is npm publish. Combined with the publishConfig block, that is the whole release path: automation decides the version and notes, and the publish command sends the single-file tarball.

The rest of the root tells you what a Vercel template repository tends to contain. turbo/ and turbo.json hold the task graph, tsconfig.json and tsup.config.ts handle configuration and bundling, bun.lock pins the workspace, .vscode/ and .cursorrules.example set editor defaults, and skills/ sits alongside scripts/ for agent-facing tooling. docs/ is the content that becomes the documentation site.

Editorial conclusion

Treat next-forge as a starting point you will diverge from, not a dependency. The vendor names in the package list are the coupling to plan for, and the overwrite behaviour in the design-system update script is the detail that bites first if you edit those components in place. Before starting, check the Node version the CLI expects, decide which of the eighteen packages you actually need, and read the migration guides for swapping providers, because those are what your exit path depends on.

Frequently asked questions

What is next-forge?

It is Vercel's MIT licensed production-grade Turborepo template for Next.js applications, designed as an opinionated starting point for building SaaS products. It ships six deployable apps and eighteen shared packages covering authentication, payments, email, analytics, observability, security, CMS, SEO, webhooks and more.

What do I need before running next-forge init?

Node.js 20 or newer, Bun or npm/yarn/pnpm, and the Stripe CLI for local webhook testing. After init you configure environment variables, set up the required service accounts such as Clerk, Stripe and Resend, and run the development server.

Can I replace the services next-forge uses?

The documentation includes migration guides for swapping providers, which matters because the package list names its vendors explicitly: Clerk for authentication, Stripe for subscriptions, Resend for transactional email, Sentry and BetterStack for observability, Arcjet for application security.

How do I update next-forge's dependencies?

bump-deps runs npm-check-updates with the deep flag and then installs. bump-ui separately re-adds all design-system components from shadcn with --overwrite against packages/design-system, which replaces local modifications to those generated components.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. vercel/next-forge on GitHub
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/vercel-next-forge.svg)](https://hysenlabs.com/projects/vercel-next-forge)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/vercel-next-forge.svg)](https://hysenlabs.com/projects/vercel-next-forge)

Was this useful?