Installation Guide

Requirements

Minimum
Node.js 20 LTS
PostgreSQL 14+
npm 10+
Disk ~1 GB for the app and dependencies

Uploads do not go to disk — they go to object storage — so the application filesystem stays small and can be read-only.

1. Install dependencies

Terminal
npm install

2. Environment

SkoolyHub reads configuration from .env in the project root. Only two values are required:

Terminal
DATABASE_URL="postgresql://user:password@host/dbname?sslmode=require"
JWT_SECRET="a-long-random-string"
Variable Required Purpose
DATABASE_URL yes PostgreSQL connection string
JWT_SECRET yes Signs portal and admin sessions; also derives the key that encrypts stored integration credentials
SECRET_KEY no Separate encryption key. Falls back to JWT_SECRET
ADMIN_EMAIL / ADMIN_PASSWORD no Seeds the first admin. Without them a random password is generated in production and printed once
NODE_ENV no production on a live server

Everything else is configuration held in the database, not in env: storage, payments, email, SMS, branding, currency and timezone. That is why they survive and travel with a database dump.

The install wizard can write .env for you on a writable filesystem, generating JWT_SECRET itself. On a read-only host such as Vercel, set the values in the host's environment configuration instead.

3. Provision the schema

Terminal
npm run db:init

This creates the core, auth and platform tables. Every school table is also created on first use by its own idempotent ensure*Schema() function, so a table you have not touched yet simply appears when you do.

There are no migration files and no migration command. Running db:init twice is safe.

4. Seed

Terminal
npm run db:seed:master      # lookup lists: blood groups, designations, payment modes…
npm run db:seed:templates   # email / SMS / push message templates

The first two are essential — they populate the dropdowns the admin screens depend on. Optionally add a demo school to explore with:

Terminal
npm run db:seed:school

It prints working sign-in details for all three portals when it finishes. Do not run it on a real school's database — it creates fictional children.

5. Start

Terminal
npm run dev      # development, http://localhost:3000
# or
npm run build && npm start

The install wizard

On first run, /install walks through:

Step What happens
Welcome Confirms the environment
Database Tests the connection, writes .env if it can, provisions the whole school schema, seeds master data and templates
Admin account Creates the first administrator
School Name, timezone, currency
License Purchase-code activation. Skipped automatically on localhost
Finish Marks the install complete

The wizard is disabled once installation completes, so it cannot be replayed against a live school.

After installing

  1. Sign in at /admin.
  2. Change the admin password immediately if one was auto-generated.
  3. Connect storage — Settings → Channels → Storage. Photo uploads fail until you do.
  4. Create the academic year — Academics → Academic Setup. Nothing else works without one.

Verify

Terminal
npx tsc --noEmit -p tsconfig.json
npx next build

Troubleshooting

Symptom Cause
DATABASE_URL is not set No .env, or the process was started before it existed
Connection refused / SSL required Missing ?sslmode=require on a managed database
"Storage is not configured" on upload Expected until you connect a provider under Settings → Channels
A route 404s in dev though the file exists Turbopack de-registered a neighbour after a folder was added. Touch the file or restart
server-only throws in a script A script imported a module that only resolves inside Next. Import the database client dynamically instead