What If Full-Stack Features Were Installable?

What If Full-Stack Features Were Installable?

●2 ●2 ●5
calendar_today ago • schedule3 min read

NextAPI, and an experiment in reusing whole application capabilities instead of code.

Every developer knows the first week of a new project. Before a single line of product code, you wire up authentication, decide how roles work, connect a database, configure Docker and build the shell your pages will live in. Then, once the foundation is in place, you start on the features, and discover you are rebuilding the same team workspace, profile page and admin area you built on the last project.

Boilerplate solved the foundation. It never solved the features.

NextAPI is my attempt to solve both. It began as a Next.js and FastAPI starter and has grown into something more ambitious: a framework where a full-stack feature (its pages, its API, its database model, its permissions and its navigation) can be installed, verified, versioned and rolled back like a package.

This article walks through what that actually means, and why I think it matters.


Part One: A Foundation You Can Use Today

NextAPI Core is a complete full-stack application, ready in minutes. It stands entirely on its own. You never have to touch the module system to get value from it.

Out of the box, you get:

Capability What it means in practice
Encrypted authentication Credentials-based auth through NextAuth v5. Login and registration payloads are AES-256-CBC encrypted on the client before a signed JWT is ever issued.
Role-based access control Admin, user and guest roles embedded in the JWT and enforced on both frontend and backend.
Machine-to-machine API accessAPI client tokens (X-API-Key / X-API-Secret) kept separate from user sessions, so integrations never borrow a person's login.
A modern async backendFastAPI with Pydantic v2 validation and SQLAlchemy 2.0.
Two databases, one switch SQLite by default with zero setup, or MongoDB with a single environment variable.
Web and native mobile from one codebase The same frontend ships as Android and iOS apps through Capacitor, authenticating against the same JWT endpoints.
A configurable app shellSidebar or top navbar, chosen once.
Production-ready deployment A Docker Compose stack with frontend, backend and an optional nginx reverse proxy with SSL.

Even setup has been designed to remove the usual failure points. Running npm run setup generates real secrets rather than placeholders, and writes the same encryption key to both the frontend and backend configuration. The two most common ways to break authentication by hand, a forgotten placeholder or keys that drift apart, simply cannot happen.

npm run setup
npm run dev

Frontend on port 3000, backend on port 8000, and you are building your product.

If you would rather start from a genuinely empty canvas, npm run init:blank permanently removes the demo pages, so there is no dead code to carry into production.

From here, the application is yours. Write your own routes, models and components. Install any npm or Python package. Change the architecture. NextAPI is not a hosted platform, and nothing about your application depends on anyone but you.


Part Two: The Problem Package Managers Never Solved

The package ecosystem is extraordinary. Need a Python library? Install it. Need a React component? There are thousands.

But what if you do not need a library? What if you need a feature?

Consider team management. It is not a component. It is a set of pages for teams, members and invitations; API endpoints behind each of them; database collections to store them; permissions governing who can do what; and navigation entries so users can find them.

Those pieces describe one capability. Yet the way we reuse software today scatters them across separate packages, separate copy-pastes and, most often, separate rewrites. Every copy starts drifting the moment it lands.

That led to the question at the heart of NextAPI:

What if the unit of reuse were the feature rather than the library?


Part Three: A Feature With a Contract

In NextAPI, a feature is a module, and every module is described by a single manifest. Here is a real one, lightly trimmed:

{
  "id": "ai-notes",
  "version": "1.0.0",
  "nextapiVersion": ">=1.0.0 <2.0.0",
  "requires": { "modules": ["profile-page@^1.0.0"] },
  "env": {
    "backend": [{ "key": "ANTHROPIC_API_KEY", "required": true, "secret": true }]
  },
  "dependencies": {
    "frontend": { "npm": { "react-markdown": "^9.0.0" } },
    "backend": { "pypi": { "anthropic": "^0.40.0" } }
  },
  "frontend": {
    "routes": [{ "path": "/notes", "protected": true, "label": "Notes" }]
  },
  "backend": {
    "router": { "module": "backend/router.py", "prefix": "/notes" },
    "collection": "module_ai_notes"
  },
  "functions": {
    "uses": ["auth.get_current_user", "profile.get_display_name"]
  }
}

Read it closely, because this is where the idea becomes concrete. In one file, this module declares:

  • the page it adds, that the page requires sign-in, and the label it shows in navigation;
  • the API router it contributes and the URL prefix it answers on;
  • the database collection it owns;
  • the npm and PyPI packages it needs;
  • the environment variables it requires, and which are secrets;
  • the other modules it depends on, with version ranges;
  • the specific functions it calls from those modules;
  • and the range of NextAPI versions it is compatible with.

A conventional package gives you code. This manifest gives the framework an understanding of a capability: what it is, what it needs and how it fits into the application around it. Everything else NextAPI does is built on that understanding.


Part Four: Two Commands, and What Really Happens

Installing a module needs no account:

nextapi add @alice/team-workspace
nextapi sync

add only records your intent in the project's lockfile. Nothing in your application changes.

sync is where the real work happens, and its defining principle is simple: nothing is written until the whole install has been proven safe. Before touching a single file, it:

  1. resolves dependency order and checks for circular dependencies;
  2. fetches any modules the new one depends on, automatically;
  3. verifies that every function a module calls is actually provided by the module it depends on;
  4. checks for route, backend package and database collection collisions.

If any check fails, the install is refused up front. An install is never left half-applied.

Only then does sync wire the feature into your real codebase:

your-app
├── app/team/page.tsx                                  new
├── backend/module_alice_team_workspace/router.py      new
├── backend/module_alice_team_workspace/models_mongo.py new
├── config/routes.ts                                   RBAC entry merged
└── .env                                               appended, your values untouched

The page appears in your sidebar or navbar automatically. The RBAC rules are merged into your configuration. The backend lands as its own isolated package.


Part Five: The Hard Problems, Solved in the Open

The idea is easy to state. What makes NextAPI worth taking seriously is how it handles the problems that make installable features genuinely difficult.

It joins your data instead of duplicating it

Suppose your application already has users, and you install a user-management module that also declares a users collection. A naive system creates a second, disconnected collection, and you now have two sources of truth about who can log in.

NextAPI detects the overlap. If the module's fields are compatible with your existing collection, sync offers to link the module to your real data instead:

'@alice/user-management' declares a "users" collection compatible with your
existing UserCollection. Link it instead of creating a separate collection? (y/N)

It goes further than matching field names:

  • Method adoption. If the module calls methods your collection class does not have yet, sync adds the module's implementations to your model. It is purely additive and never overwrites a method your application already relies on.
  • Real-data checks. A schema can match on paper and still not match reality. sync samples your actual MongoDB documents, and if a field your model declares as required is missing from existing records, it asks before relaxing it:
'users' collection: 'created_at' is declared required, but missing from
214/1,048 existing documents. Demote 'created_at' to optional in your
host's UserMongo model to match reality? (y/N)
  • Remembered decisions. Updates to a linked module re-link automatically. If a future version stops matching, it falls back safely and tells you exactly what happened.

When fields do not match, the module installs against its own collection and you receive a precise, field-by-field report of what did not line up, which is something concrete for the module's author to fix.

This is the difference between installing code into an empty project and integrating a feature into a living system.

Modules depend on capabilities, not just packages

Modules can declare the functions they provide and the functions they use. A support-chat module can call profile.get_display_name, provided by a profile module, and the registry confirms that capability exists before either module installs.

Package managers resolve graphs of libraries. NextAPI resolves a graph of application capabilities.

Names never collide

Two authors can both build a module with a /profile page and a profile collection. At install time, NextAPI automatically namespaces pages, backend code and database storage per module. Authors can write as though their module is the only one that will ever exist.

Versioned like real software

  • Versions follow semver and are immutable once published.
  • A bad release can be yanked from new installs without breaking anyone already using it.
  • Compatible version ranges are resolved to a single shared version automatically, and genuine conflicts are reported with both requirements named.
  • Stateless modules can opt into running multiple major versions side by side.
  • Stored data carries its own schemaVersion. Changing the shape of persisted documents requires publishing a normalizer that upgrades older documents on read, so no previously stored record ever becomes unreadable.

Every risky change is deliberate and reversible

Some modules replace an existing page rather than adding one: a custom login screen, a redesigned landing page. That requires an explicit acknowledgement written into the manifest itself, so it cannot be scripted past a prompt. Before anything is replaced, the original is captured as a full snapshot, and nextapi rollback /login restores it.

Files you have edited by hand since the last sync are detected and left alone. nextapi list flags drift, and nextapi remove will not discard your changes without --force.


Part Six: It Is Your Code

None of this turns your application into a black box.

After sync, a module's files are committed into your project as ordinary, readable source code, marked in clearly generated regions. You can edit them immediately. There is no runtime dependency on the registry. If the registry disappeared tomorrow, your application would keep running exactly as it does today.

That was a non-negotiable design goal. The registry distributes capabilities. It never owns them.


Part Seven: Building and Sharing Modules

The registry at nextapi.app is where modules are published, discovered and installed. Building for it is designed to be as approachable as using it.

  • Build in the browser. Start from a working template and edit in a full code editor that understands TypeScript, JavaScript, Python and JSON, with errors marked on the exact line.
  • Build with AI. The AI Builder writes an entire module (manifest, backend, page and preview data) from a description. What sets it apart is discipline: it loads design standards before laying out a page, looks up a library's real documentation instead of guessing, lints its own output for accessibility issues such as contrast and reduced motion, and runs the same validation that gates every publish. Its output is identical in form to a hand-written module. The only difference is who typed it.
  • Publish with confidence. nextapi validate checks the schema, capabilities and file paths locally, and every publish is re-validated on the server. Each module must ship maintainer-facing implementation notes explaining what it assumes about the host application.
  • Share privately. Publish a private module and share it with specific people by username.
  • Fork with credit. Fork any public module to adapt it. The original author is recorded permanently and cannot be removed from the fork.

Part Eight: Core Stands on Its Own

This is worth stating plainly, because the registry can make the project appear more complex than it is.

You can use NextAPI Core purely as a full-stack foundation and ignore the module ecosystem entirely. The registry is a layer on top, not a requirement underneath:

                    Registry
                       |
             +---------+---------+
             |         |         |
          Module A  Module B  Module C
             |         |         |
             +---------+---------+
                       |
                  NextAPI Core
                       |
              +--------+--------+
              |                 |
           Next.js           FastAPI
              |                 |
              +--------+--------+
                       |
                    Database

NextAPI should be useful before the ecosystem exists. The registry should make it more powerful, never necessary.


What I Am Actually Building

I am not building another package manager, and I have no interest in replacing npm or PyPI. They solve a different problem, and they solve it well.

What interests me is moving one level higher. A library knows what functions it exports. A NextAPI module knows:

  • "I add these pages, and they require sign-in."
  • "I expose these API routes."
  • "I own this data, and this is the version of its shape."
  • "I need these permissions, packages and secrets."
  • "I depend on these capabilities from other modules."
  • "I belong in the navigation, here."

Once a framework has that information, it can do far more than copy code into a project. It can reason about how a feature fits into an application: whether it is safe, whether it conflicts, whether it should join existing data, and how to undo it.

Where Things Stand

NextAPI is open source under the MIT license and actively evolving. The foundation is solid, the module system already handles problems most tools never attempt, and plenty of hard work remains: richer migrations, broader host compatibility and a growing library of modules.

The underlying idea is one I believe is worth pursuing:

Instead of rebuilding the same full-stack features over and over, what if we could install the capability itself?

That is what NextAPI has become. Not just a starter kit, and not just a registry, but an attempt to move reusable software one step closer to the application itself.

Try it:

5 Comments

2 votes
1 vote
2 votes
1
2
🔥 Join developers growing publicly
Share your knowledge, build in public, and grow your developer presence with a global community.

More Posts

Dashboard Operasional Armada Rental Mobil dengan Python + FastAPI

Masbadar - Mar 12

Your Tech Stack Isn’t Your Ceiling. Your Story Is

Karol Modelski - Apr 9

Excited to Share My Latest Full-Stack Project: NeighborHelp! 🤝

Md Mijanur Molla - Jul 29

Lighthouse’s New Baseline Features Audit: What Developers Should Do With It

ApogeeWatcherverified - Aug 3

Navigating the Modern Web Landscape: A Full-Stack Perspective

Next Big Creative - Jun 2
chevron_left
166 Points • 9 Badges
Cape Town, South Africa • mokhan.co.za
1Posts
0Comments
1Connections
Lead Developer in Business Automation & AI, I design and deliver scalable solutions that turn complex challenges into streamlined, efficient systems.

Related Jobs

View all jobs →

Commenters (This Week)

1 comment
1 comment
1 comment

Contribute meaningful comments to climb the leaderboard and earn badges!