Neutrino Docs
Getting Started

Project Structure

Understand the nno-stack-starter monorepo layout, key packages, and configuration files.

Project Structure

A Neutrino platform project is a pnpm monorepo scaffolded from the nno-stack-starter template. It uses Turborepo for build orchestration and is designed to deploy entirely to Cloudflare — Pages for the console frontend, Workers for backend services.


Top-level layout

your-platform/
├── apps/
│   └── console/             # React 19 console shell — deploys to CF Pages
├── features/                # Custom feature packages (your domain logic)
│   ├── billing/             # @your-org/feature-billing
│   ├── settings/            # @your-org/feature-settings
│   └── stacks/              # @your-org/feature-stacks
├── packages/                # Shared internal libraries
│   ├── core/                # Naming utilities and constants
│   ├── sdk/                 # Feature SDK, hooks, and types
│   ├── ui-core/             # shadcn/ui components + shared UI
│   ├── ui-auth/             # Auth UI components
│   └── logger/              # Structured logging
├── tooling/                 # Shared ESLint, TypeScript, Tailwind configs
├── .env                     # Local environment variables
├── pnpm-workspace.yaml      # Monorepo workspace definition
├── turbo.json               # Turborepo pipeline config
└── package.json             # Root scripts and workspace-wide deps

apps/console

The console shell is a thin React 19 app that:

  • Bundles your activated feature packages at build time via the virtual:feature-registry Vite plugin
  • Deploys as a static site to Cloudflare Pages
  • Uses TanStack Router for file-based routing
  • Uses Better Auth's React client (pointing at your platform's auth Worker)

Key files:

apps/console/
├── src/
│   ├── main.tsx             # App entry point
│   ├── router.tsx           # TanStack Router config
│   └── routes/              # File-based routes
├── vite.config.ts           # Vite + NnoPlugin config (feature auto-discovery)
├── vite-plugins/            # Custom Vite plugins (feature-registry, etc.)
├── wrangler.toml            # CF Pages config (routes, KV bindings)
└── .env                     # VITE_AUTH_URL, VITE_PLATFORM_ID, etc.

Environment variables (in apps/console/.env):

VariablePurpose
VITE_AUTH_URLURL of your platform's auth Worker, e.g. https://auth.svc.default.<platformId>.nno.app
VITE_PLATFORM_IDYour Neutrino platform ID (assigned at onboarding)
VITE_NNO_REGISTRY_URLNeutrino registry service URL (default: https://registry.svc.nno.app)

features/

Feature packages are the primary extension point. Each is a pnpm workspace package that:

  • Exports a featureManifest object describing its routes, sidebar nav, and permissions
  • Declares "neutrino": { "type": "feature" } in package.json for auto-discovery
  • Can include a Cloudflare Worker for backend logic
features/billing/
├── src/
│   ├── index.ts             # Exports featureManifest
│   ├── routes/              # TanStack Router route components
│   ├── components/          # Feature-scoped UI components
│   └── hooks/               # TanStack Query hooks
├── package.json             # Must declare "neutrino": { "type": "feature" }
└── tsconfig.json

The Vite plugin scans all @your-org/feature-* packages at build time, collects their manifests, and injects them into the console via a virtual module. You do not manually register features — install the package, set it to enabled: true in your config, and rebuild.


packages/

Shared libraries used across the console and feature packages:

PackagePurpose
@neutrino-io/coregenerateId, buildResourceName, naming constants. Import these — never invent your own.
@neutrino-io/sdkFeature SDK primitives: useFeatureContext, useTenantId, useStackId, shared types
@neutrino-io/ui-coreshadcn/ui components + PageHeader, DataTable, layout primitives
@neutrino-io/ui-authSign-in, sign-up, and session UI components
@neutrino-io/loggerStructured logging for both browser and Worker environments

Build packages in dependency order before running the console:

pnpm --filter @neutrino-io/core build
pnpm --filter @neutrino-io/sdk build
pnpm --filter @neutrino-io/ui-core build

Key configuration files

turbo.json

Defines the Turborepo build pipeline. Ensures packages are built before the apps that consume them. You rarely need to edit this unless you add a new build output type.

pnpm-workspace.yaml

Lists workspace globs (apps/*, features/*, packages/*, tooling/*). If you add a new feature or package in a non-standard location, register it here.

.env (root)

Root-level env vars shared across all workspace packages during local dev. Service-specific vars live in apps/console/.env or services/*/.env.

# .env (root)
NODE_ENV=development

wrangler.toml (apps/console)

Configures the CF Pages project: routes, KV namespace bindings, D1 database bindings, and compatibility_date. During local dev, Wrangler injects these bindings via pnpm dev.


Next steps

On this page