---
title: "How to deploy an Elysia + TanStack dashboard on Rock8Cloud"
description: "Deploy an authenticated dashboard to Rock8Cloud in one click - Elysia API on Bun, a TanStack Start web app, PostgreSQL provisioned and wired, with a seeded login ready on the first deploy."
tech: "Elysia + TanStack"
icon: bun
category: fullstack
pubDate: 2026-07-26
image: /how-to/og/howto.png
imageAlt: "How to deploy an Elysia and TanStack dashboard on Rock8Cloud"
headerImage: true
heroImage:
  src: /how-to/dashboard-demo.webp
  alt: "The deployed dashboard signed in as demo@example.com, showing the todo list"
  width: 1920
  height: 761
exampleRepo: https://github.com/rock8-cloud/elysia-tanstack-dashboard-monorepo
ctaTitle: "Ship your dashboard."
ctaTitleHighlight: "Signed in on day one."
ctaSubtitle: "An Elysia API, a TanStack Start web app and PostgreSQL - provisioned together, wired to each other, live on the first deploy."
ctaIcons: [bun, tanstack, postgresql, typescript]
order: 5
steps:
  - name: "Start from the blueprint"
    text: "Open the Elysia + TanStack Dashboard blueprint. Rock8Cloud clones the monorepo into your GitHub account and creates two services from it, the Elysia API and the TanStack Start web app."
  - name: "Hit Deploy"
    text: "Rock8Cloud provisions PostgreSQL, generates the auth secret, and gives each service the other's public URL. Migrations run as the API boots and a demo account is seeded."
  - name: "Sign in"
    text: "Read SEED_USER_PASSWORD from the API service's environment variables and sign in as demo@example.com at /login on the web URL."
faq:
  - q: "What do I need to configure before deploying?"
    a: "Nothing. The blueprint clones the repo, provisions PostgreSQL and passes it in as DATABASE_URL, generates the auth secret, and sets the cross-service URLs. The first deploy gives you a working signed-in dashboard."
  - q: "How do the API and the web app find each other?"
    a: "Automatically. The API gets its own public URL as BETTER_AUTH_URL and the web origin as CORS_ORIGIN, and the web app is built against the API public URL. There is no manual URL setup."
  - q: "How do I log in the first time?"
    a: "The API seeds demo@example.com with a password generated for your deployment. Read SEED_USER_PASSWORD from the API service environment variables. Change the password or delete the account once you have your own user, and set SEED_DEFAULT_USER=false to stop seeding."
  - q: "Do I need to run migrations?"
    a: "Migrations run automatically when the API starts. To change the schema, edit apps/server/src/db/schema/*, run bun run db:generate, then commit and push."
  - q: "Why does moving the API URL need a rebuild?"
    a: "VITE_SERVER_URL is inlined by Vite at build time, so it is passed as a Docker build argument rather than a runtime variable. If the API moves to a different URL the web service needs a rebuild, not just a restart."
---

An authenticated dashboard in one deploy - an [Elysia](https://elysiajs.com/) API on [Bun](https://bun.sh/) and a [TanStack Start](https://tanstack.com/start) web app, managed as a single [Turborepo](https://turborepo.dev/) monorepo. Rock8Cloud provisions the database, generates the secrets, and has you signed in before you have opened an editor.



[Elysia + TanStack example](https://github.com/rock8-cloud/elysia-tanstack-dashboard-monorepo)

[1-click clone & deploy](https://app.rock8.cloud/new-deployment?blueprint=elysia-tanstack-dashboard-monorepo&utm_source=howto&utm_medium=landing&utm_campaign=howto&utm_content=elysia-dashboard)



Or ask an agent instead of clicking. With Rock8Cloud [connected over MCP](/how-to/connect-claude), `deploy_blueprint` with the `elysia-tanstack-dashboard-monorepo` slug forks the same template into your GitHub account, creates the project with its services, and starts the first build.

## Deploy in one click

The blueprint clones the monorepo into your GitHub account, then builds two services from it - the Elysia API (port 3001) and the TanStack Start web app (port 3000). A managed PostgreSQL database is provisioned and passed to the API as `DATABASE_URL`.

The services learn each other's addresses at deploy time. The API receives its own public URL as `BETTER_AUTH_URL` and the web origin as `CORS_ORIGIN`, and the web app is built against the API public URL. Nothing about that is yours to wire.

## What is in the box

| Layer | Technology |
|---|---|
| API | Elysia on Bun, port 3001 |
| Type safety | [Eden](https://elysiajs.com/eden/overview), the web app imports the API type directly |
| Auth | [better-auth](https://better-auth.com/) cookie sessions, email and password, OIDC-ready |
| Database | PostgreSQL with [Drizzle ORM](https://orm.drizzle.team/) |
| Web | TanStack Start, TanStack Query and [shadcn/ui](https://ui.shadcn.com/) on Base UI, port 3000 |

There is a working todo vertical slice in the repo showing the route to service to query layering, so the first feature you add has a pattern to copy.

## Your first login

The API seeds `demo@example.com` with a password generated for your deployment. Read it from `SEED_USER_PASSWORD` in the API service's environment variables, then sign in at `/login` on the web URL.



> **Pro tip:** Sign-up is open by default, so anyone who reaches your web URL can register. Restrict or disable `emailAndPassword` in `apps/server/src/lib/auth.ts` before putting anything real behind it.



Change the demo password or delete the account once you have your own user. Set `SEED_DEFAULT_USER=false` to stop seeding entirely.

## Changing the schema

Migrations run automatically when the API starts. To change the schema:

1. Edit `apps/server/src/db/schema/*`
2. Run `bun run db:generate`
3. Commit and push

Keep the route to service to query boundaries when adding features. An oxlint rule enforces that only `src/db` touches Drizzle.

## Moving the API

`VITE_SERVER_URL` is inlined by Vite at build time, so it travels as a Docker build argument rather than a runtime variable. If you move the API to a different URL, the web service needs a rebuild rather than a restart.
