Building on Graviton

Compared to plain Next.js

See what changes when your Next.js App Router code runs on Stardeck: the runtime, the data layer, auth, deploys and who keeps the app current.

A Stardeck app is stock Next.js: App Router, React Server Components, page.tsx, route.ts, layout.tsx, Tailwind. Nothing proprietary replaces the framework, and your React is portable.

What differs is where requests are decided, where data lives, who holds credentials and who keeps the app current.

At a glance

On your own Next.js appOn GravitonWhy
Choose a host and run deployMerge a pull request into main, then publishStandard size builds to a Cloudflare Worker; Large builds a Node.js server with more memory
Pick a runtime per routeWorker runtime at Standard sizeNo Node.js runtime at Standard, which is also why middleware.ts must not be renamed to proxy.ts
Provision Postgres, pick an ORM, own migrationsData Store + data-store-sdk (Kysely)Schema changes are platform operations or Module ledger entries; the driver is HTTP, so no interactive transactions
Add NextAuth, Clerk, or roll your ownproject-authSign-in, RBAC, SSO and admin/user dashboards ship with it; visibility is enforced at the edge
Guard routes in middlewareGuard in the layout and in each API handlerHost classification, tenant lookup and public/internal gating happen before your code; API paths are never edge-gated
vercel cron or a cron containerscheduling-sdkThe platform calls your deployment on a schedule
Wire Stripe, an email provider, an S3 bucketpayments-sdk, email-sdk, storage-type Data StoreThe platform holds credentials; every call is HMAC-signed by the SDK
Rely on ISR and the data cacheTreat rendering as per-request; cache deliberatelyNo incremental cache at Standard size. See Constraints
Edit next.config.ts freelyAsk Stardeck for config changesUpdates edit that file
One project per audience: site, admin, POSSurfaces in one repoEach gets its own hostname, icon and install identity from one deploy
Own your dependency and framework upgradesUpdates move the app forwardEach released version is merged into your repo like any Git merge
.env.local you maintainnpm run env:pull from the platformSecrets are stored and decrypted by the platform, per environment
Webhooks to localhost via a tunnelExercise inbound traffic in the sandboxNothing inbound is routed to a local dev server, by design

What this buys and what it costs

flowchart TB
    subgraph Y["What you stop owning"]
        Y1["Infrastructure and credentials"]
        Y2["Auth, RBAC and the sign-in surface"]
        Y3["Framework and dependency upgrades"]
        Y4["Hostnames, TLS and PWA identity per audience"]
    end
    subgraph C["What you accept"]
        C1["Worker limits at Standard size, including a 10 MiB bundle"]
        C2["No interactive database transactions"]
        C3["Some files and operations are platform-owned"]
        C4["Deploys go through the platform, not your CI"]
    end
    Y --> V["One codebase, many audiences,<br/>that keeps moving forward"]
    C --> V

Each constraint is enforced by something you can see: a lint rule, a build failure or a file header.

Updates

New apps start from a shared foundation and don't run platform migrations. When Stardeck releases a new version, the app shows Update available and you merge it, in-product or locally. The update brings new SDK versions, config changes and a new AGENTS.md.

  • Stay on the SDK surface. Code that uses an SDK's documented API survives updates. Code that reaches around it (hand-built platform requests, copies of generated files) is what conflicts or breaks.
  • Don't edit AGENTS.md. The app keeps Stardeck's copy, and updates change it. Put project conventions in a separate file.

Still Next.js

Things that work exactly as you expect, with no Stardeck-specific wrapper: the App Router and route groups, Server Components and Server Actions, layout.tsx composition, streaming, next/image (against configured hosts), Tailwind, react-hook-form, TanStack Query, Zod, Playwright and Vitest.

If a Next.js pattern is not listed on the Constraints page as restricted, assume it works.