NNO Docs
Guides

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:


Prerequisites

Before starting, ensure you have the following installed and available:

  • Node.js >= 18 (node --version)
  • pnpm >= 8 (pnpm --version; install via npm install -g pnpm)
  • GitHub PAT with read:packages scope — 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-console

Or 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_TOKEN

Add 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 install

Verify that @neutrino-io/* packages resolved correctly:

ls node_modules/@neutrino-io
# Expected: core  sdk  ui-auth  ui-core  feature-billing  feature-settings

Troubleshooting

ErrorCauseFix
401 Unable to authenticateGITHUB_TOKEN not set or PAT expiredRe-export the token; regenerate if expired
404 Not Found for @neutrino-io/*.npmrc registry entry missing or wrong scopeConfirm .npmrc has @neutrino-io:registry=https://npm.pkg.github.com
403 ForbiddenNo package access on the GitHub orgAsk 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.local

Key variables:

VariableDescriptionExample
VITE_GATEWAY_URLNNO API gateway URLhttps://gateway.svc.nno.app
VITE_AUTH_URLAuth worker URL for this platformhttps://auth.svc.default.<platformId>.nno.app
VITE_PLATFORM_IDYour platform's 10-char nano-idk3m9p2xw7q

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 dev

The console shell starts on http://localhost:5173 by default (Vite's default port). You should see the NNO authentication screen.

What happens at startup:

  1. Vite builds the shell, running the neutrino-feature-discovery plugin which scans package.json for all @neutrino-io/feature-* dependencies and generates the virtual:feature-registry module.
  2. The shell boots, FeatureRegistry.initialize() loads all enabled features from features.config.ts, and the route tree and sidebar are built — entirely from static imports bundled at build time, with no network round-trips.
  3. 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-settings

The 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 featureManifest from its barrel (src/index.ts)
  • The package declares "neutrino": \{"type": "feature"\} in its own package.json
  • enabled: true is set in features.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

  1. 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 build and output directory to apps/console/dist
  2. Add environment variables in the Pages project settings (Settings → Environment variables):

    • VITE_GATEWAY_URL — NNO gateway URL
    • VITE_AUTH_URL — your platform's auth worker URL
    • VITE_PLATFORM_ID — your platform ID
    • GITHUB_TOKEN (or NODE_AUTH_TOKEN) — PAT for installing @neutrino-io/* during CI builds
  3. Add repository secret for CI package installs. The starter's .github/workflows/deploy.yml expects PACKAGE_READ_TOKEN in repository secrets:

    Repository → Settings → Secrets and variables → Actions → New repository secret
    Name: PACKAGE_READ_TOKEN
    Value: PAT with read:packages scope
  4. Trigger a deployment: push to main. GitHub Actions runs pnpm build then wrangler 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.app

For example, if your platform ID is k3m9p2xw7q:

https://auth.svc.default.k3m9p2xw7q.nno.app

Set 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

SymptomLikely CauseFix
pnpm install fails with 401GITHUB_TOKEN not set or expiredExport a valid PAT: export GITHUB_TOKEN=ghp_...
Package @neutrino-io/feature-* not found (404).npmrc missing or wrong scope keyVerify @neutrino-io:registry=https://npm.pkg.github.com is present
Shell starts but no sidebar items appearAll features disabled in features.overrides.tsSet enabled: true for at least one feature
Feature installed but not auto-discoveredPackage missing "neutrino": \{"type": "feature"\} in its package.json, or not following @neutrino-io/feature-* namingConfirm both conditions; restart dev server
CORS errors when calling the gatewayVITE_GATEWAY_URL points to wrong environmentCheck the URL matches your intended environment (prod vs staging)
Auth cookie not set after sign-inAuth worker URL misconfigured or mismatched with current originConfirm VITE_AUTH_URL matches the provisioned auth worker for your platform
wrangler pages deploy failsMissing CF API token or wrong project nameRun wrangler login and confirm Pages project name matches your wrangler.toml
CI build fails installing @neutrino-io/*PACKAGE_READ_TOKEN secret not set in repoAdd 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 featureManifest export
  • Configure environments: Multi-Environment Guide — managing .env files 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

On this page