Platform Setup Guide
Platform Setup Guide
Overview
This guide walks a Platform Developer through setting up a client platform console from scratch using nno-stack-starter as the foundation. By the end you will have a running local console shell that authenticates against the NNO backend, auto-discovers feature packages, and is ready to deploy to Cloudflare Pages.
Who this is for: Developers building a client platform that consumes @neutrino-io/* packages. This is not the guide for contributing to nno-app-builder itself — that is the core monorepo maintained by NNO. Platform Developers work in a separate per-platform repo created from the nno-stack-starter template.
For deep architectural context, see:
- Multi-Repo Architecture — how
nno-app-builder,nno-stack-starter, and per-platform repos relate - Shell Feature Config — how the console shell auto-discovers and boots feature packages
Prerequisites
Before starting, ensure you have the following installed and available:
- Node.js >= 18 (
node --version) - pnpm >= 8 (
pnpm --version; install vianpm install -g pnpm) - GitHub PAT with
read:packagesscope — required to install@neutrino-io/*packages from GitHub Packages. See Configure Package Access below. - Wrangler CLI (optional, required for deployment) —
npm install -g wrangler
You also need collaborator access on the neutrino-platform GitHub organization so the PAT can resolve the private @neutrino-io package registry.
Clone the Starter
nno-stack-starter is the canonical template for all client platform repos. When a platform is provisioned through the NNO Portal, the CLI Service creates a new repo from this template automatically. If you are setting up manually (for development or testing), clone it directly:
# Clone the template as your platform repo
git clone https://github.com/neutrino-platform/nno-stack-starter.git my-platform-console
cd my-platform-consoleOr use GitHub's "Use this template" button to create a new repo under your organization.
The starter contains a minimal console shell (apps/console/) that depends on @neutrino-io/sdk, @neutrino-io/ui-auth, @neutrino-io/ui-core, @neutrino-io/feature-billing, and @neutrino-io/feature-settings. No features are enabled by default — they are activated at runtime via features.config.ts.
Configure Package Access
@neutrino-io/* packages are hosted on GitHub Packages, not the public npm registry. You must configure your local environment to authenticate against npm.pkg.github.com before running pnpm install.
1. Generate a GitHub PAT
GitHub → Settings → Developer settings → Personal access tokens → Tokens (classic)
→ Generate new token (classic)
→ Scopes: check read:packages
→ Copy the token (starts with "ghp_")2. Add .npmrc to your project root
The starter already includes a .npmrc file. Verify it contains:
@neutrino-io:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}Do not hardcode your token in .npmrc — always use the $\{GITHUB_TOKEN\} environment variable form. The .npmrc is committed to the repo; your token must stay out of version control.
3. Export the token in your shell
export GITHUB_TOKEN=ghp_YOUR_TOKENAdd this to your shell profile (~/.zshrc, ~/.bashrc) to persist it across sessions.
For full details on PAT scopes, CI integration, and multi-scope configurations, see the Package Registry Guide.
Install & Verify
With the registry configured, install dependencies:
pnpm installVerify that @neutrino-io/* packages resolved correctly:
ls node_modules/@neutrino-io
# Expected: core sdk ui-auth ui-core feature-billing feature-settingsTroubleshooting
| Error | Cause | Fix |
|---|---|---|
401 Unable to authenticate | GITHUB_TOKEN not set or PAT expired | Re-export the token; regenerate if expired |
404 Not Found for @neutrino-io/* | .npmrc registry entry missing or wrong scope | Confirm .npmrc has @neutrino-io:registry=https://npm.pkg.github.com |
403 Forbidden | No package access on the GitHub org | Ask a maintainer to grant access to your GitHub account |
Environment Configuration
The console shell reads configuration from environment variables. The starter ships with a .env.example — copy it to .env.local for local development:
cp .env.example .env.localKey variables:
| Variable | Description | Example |
|---|---|---|
VITE_GATEWAY_URL | NNO API gateway URL | https://gateway.svc.nno.app |
VITE_AUTH_URL | Auth worker URL for this platform | https://auth.svc.default.<platformId>.nno.app |
VITE_PLATFORM_ID | Your platform's 10-char nano-id | k3m9p2xw7q |
The auth worker URL follows the Pattern B DNS convention: auth.svc.default.<platformId>.nno.app. See DNS Naming for the full hostname structure.
For configuring separate local, staging, and production environments, see the Multi-Environment Guide.
Run the Console Shell
Start the development server:
pnpm devThe console shell starts on http://localhost:5173 by default (Vite's default port). You should see the NNO authentication screen.
What happens at startup:
- Vite builds the shell, running the
neutrino-feature-discoveryplugin which scanspackage.jsonfor all@neutrino-io/feature-*dependencies and generates thevirtual:feature-registrymodule. - The shell boots,
FeatureRegistry.initialize()loads all enabled features fromfeatures.config.ts, and the route tree and sidebar are built — entirely from static imports bundled at build time, with no network round-trips. - The authentication screen appears. Sign in using your platform credentials to reach the main console.
Feature auto-discovery means you do not need to manually register packages. Installing an @neutrino-io/feature-* package that declares "neutrino": \{"type": "feature"\} in its package.json and exports a featureManifest is sufficient — the Vite plugin picks it up automatically on the next build. See Shell Feature Config for the full auto-discovery spec.
Activate a Feature
Feature packages are pre-listed in the starter's package.json but disabled by default in features.config.ts. To enable an existing package:
Using a pre-installed package (e.g. @neutrino-io/feature-settings)
Open src/config/features.overrides.ts and set enabled: true for the feature:
// src/config/features.overrides.ts
export const featureOverrides = {
settings: {
enabled: true,
},
};Restart the dev server. The Settings entry appears in the sidebar.
Installing a new feature package
pnpm add @neutrino-io/feature-settingsThe Vite plugin auto-discovers it on the next build. You can then enable it via features.overrides.ts as above.
Verify it appears: after restarting pnpm dev, the feature's sidebar entry should be visible. If it does not appear, confirm:
- The package exports
featureManifestfrom its barrel (src/index.ts) - The package declares
"neutrino": \{"type": "feature"\}in its ownpackage.json enabled: trueis set infeatures.overrides.ts
For building your own custom feature packages, see the Feature Development Guide.
Deploy to Cloudflare Pages
Prerequisites
- A Cloudflare account with Pages access
- Wrangler CLI authenticated:
wrangler login
First Deployment Checklist
-
Create a Pages project in the Cloudflare dashboard:
- Cloudflare Dashboard → Workers & Pages → Create → Pages → Connect to Git
- Connect your platform repo; set build command to
pnpm buildand output directory toapps/console/dist
-
Add environment variables in the Pages project settings (Settings → Environment variables):
VITE_GATEWAY_URL— NNO gateway URLVITE_AUTH_URL— your platform's auth worker URLVITE_PLATFORM_ID— your platform IDGITHUB_TOKEN(orNODE_AUTH_TOKEN) — PAT for installing@neutrino-io/*during CI builds
-
Add repository secret for CI package installs. The starter's
.github/workflows/deploy.ymlexpectsPACKAGE_READ_TOKENin repository secrets:Repository → Settings → Secrets and variables → Actions → New repository secret Name: PACKAGE_READ_TOKEN Value: PAT with read:packages scope -
Trigger a deployment: push to
main. GitHub Actions runspnpm buildthenwrangler pages deploy. The first build takes 2–3 minutes.
For custom domain setup and DNS configuration, see the DNS Operations Guide.
Connect to NNO Backend
The console shell communicates with two NNO backend endpoints: the API gateway and your platform's auth worker.
Gateway URL
All API calls are routed through the NNO gateway:
- Production:
https://gateway.svc.nno.app - Staging:
https://gateway.svc.stg.nno.app
Set this as VITE_GATEWAY_URL in your environment.
Auth Worker URL
Each platform has a dedicated auth worker on the default stack. The hostname follows Pattern B DNS:
auth.svc.default.<platformId>.nno.appFor example, if your platform ID is k3m9p2xw7q:
https://auth.svc.default.k3m9p2xw7q.nno.appSet this as VITE_AUTH_URL. The shell's auth provider reads this URL to perform session checks and token exchanges.
See DNS Naming for the complete Pattern A / Pattern B hostname reference and staging variants.
Troubleshooting
| Symptom | Likely Cause | Fix |
|---|---|---|
pnpm install fails with 401 | GITHUB_TOKEN not set or expired | Export a valid PAT: export GITHUB_TOKEN=ghp_... |
Package @neutrino-io/feature-* not found (404) | .npmrc missing or wrong scope key | Verify @neutrino-io:registry=https://npm.pkg.github.com is present |
| Shell starts but no sidebar items appear | All features disabled in features.overrides.ts | Set enabled: true for at least one feature |
| Feature installed but not auto-discovered | Package missing "neutrino": \{"type": "feature"\} in its package.json, or not following @neutrino-io/feature-* naming | Confirm both conditions; restart dev server |
| CORS errors when calling the gateway | VITE_GATEWAY_URL points to wrong environment | Check the URL matches your intended environment (prod vs staging) |
| Auth cookie not set after sign-in | Auth worker URL misconfigured or mismatched with current origin | Confirm VITE_AUTH_URL matches the provisioned auth worker for your platform |
wrangler pages deploy fails | Missing CF API token or wrong project name | Run wrangler login and confirm Pages project name matches your wrangler.toml |
CI build fails installing @neutrino-io/* | PACKAGE_READ_TOKEN secret not set in repo | Add the secret under Repository → Settings → Secrets and variables → Actions |
Next Steps
With the shell running and connected to NNO:
- Build a custom feature: Feature Development Guide — how to author a feature package with routes, sidebar navigation, and the
featureManifestexport - Configure environments: Multi-Environment Guide — managing
.envfiles for local, staging, and production - Architecture reference: Multi-Repo Architecture — understand how your platform repo fits into the broader NNO ecosystem
- Shell internals: Shell Feature Config — the complete spec for
features.config.ts, auto-discovery, and the boot sequence