Skip to main content
OpenBookDocumentation

Setup Guide

Prerequisites

  • Node.js 18+ (recommended: 20 LTS)
  • npm 9+

Quick Start

  1. Clone the repository
    git clone https://github.com/your-org/openbook.git
    cd openbook
  2. Install dependencies
    npm install
  3. Start the development server
    npm run dev

    The database is created and migrations are applied automatically. No .env file is required for local development.

First-Time Setup

  1. Visit /admin/register to create an admin account. The first person to register becomes the admin.
  2. Configure your town at /admin/setup (name, slug, branding).
  3. Upload budget data at /admin/upload.
  4. Map columns and confirm. Your portal is now live.

Environment Variables

VariableRequiredDescription
DATABASE_URLNoSQLite database file path (defaults to file:./dev.db)

Deployment Guide

OpenBook runs locally with SQLite out of the box, but for a public-facing portal you'll want to deploy it to a hosting provider with a production database. This section walks through the recommended path.

Deploying to Vercel (Recommended)

Vercel is the easiest way to get OpenBook online. It auto-builds on every push to your main branch, handles SSL, and has a free tier that works fine for municipal portals.

  1. Fork the repository

    Go to https://github.com/your-org/openbook and click Fork. This gives your town its own copy of the codebase.

  2. Connect to Vercel

    Sign up at vercel.com, click Add New Project, and import your forked repo. Vercel will detect the Next.js framework automatically.

  3. Add environment variables

    In the Vercel project settings, go to Environment Variables and add:

    VariableValue
    DATABASE_URLYour Postgres connection string (see Database Migration below)

    For the database, grab a free Postgres instance from neon.tech or supabase.com. Both offer free tiers that are more than enough for a single town's budget data.

  4. Deploy

    Click Deploy. Vercel builds the app and gives you a public URL like openbook-yourtown.vercel.app. Every push to your main branch triggers a new deployment automatically.

Database Migration (SQLite to Postgres)

Locally, OpenBook uses SQLite. For production you need to switch to Postgres. Here's how:

  1. Get a Postgres connection string

    It looks something like: postgresql://user:password@host:5432/dbname

  2. Update the Prisma schema

    In prisma/schema.prisma, change the datasource provider:

    datasource db {
      provider = "postgresql"  // was "sqlite"
      url      = env("DATABASE_URL")
    }
  3. Set the environment variable
    DATABASE_URL="postgresql://user:password@host:5432/dbname"
  4. Run migrations
    npx prisma migrate dev

Note:Your local SQLite data does not carry over when you switch to Postgres. After migrating, re-upload your budget data through the admin panel. The schema and tables are created by the migration — it's just the row data that doesn't transfer.

Custom Domain Setup

Once your portal is deployed, you can point a real domain at it.

  1. Add the domain in Vercel

    Go to your project's Settings → Domains and add your domain (e.g., budget.townname.gov).

  2. Add a CNAME record in your DNS provider

    Create a CNAME record pointing to:

    cname.vercel-dns.com

    For .govsubdomains, your IT department sets this in the town's DNS management. For domains on GoDaddy, Namecheap, Cloudflare, etc., do the same thing in their DNS panel.

  3. SSL is automatic

    Vercel provisions and renews SSL certificates automatically once the DNS record propagates. No extra configuration needed.

IT Department Handoff

In most towns, the person setting up OpenBook (town manager, finance director) is not the same person who manages DNS and hosting. Here's how the work splits:

What the town manager does:

  • Fork the OpenBook repo to the town's GitHub account
  • Run the app locally and create the admin account
  • Configure the town name, slug, and branding
  • Upload budget data and verify everything looks right

What IT does:

  • Connect the forked repo to Vercel
  • Set up a Postgres database (Neon or Supabase free tier)
  • Add the DATABASE_URL environment variable in Vercel
  • Point the subdomain (e.g., budget.townname.gov) via CNAME
  • Verify the deployment is live and SSL is working

IT Handoff Checklist

  1. Fork the repo at https://github.com/your-org/openbook
  2. Create a Vercel account and import the forked repo
  3. Provision a Postgres database (Neon: neon.tech, Supabase: supabase.com)
  4. Copy the connection string and add it as DATABASE_URL in Vercel environment variables
  5. Update prisma/schema.prisma provider to "postgresql" and commit the change
  6. Deploy — Vercel builds automatically on push
  7. Add custom domain in Vercel and set the CNAME record to cname.vercel-dns.com
  8. Wait for DNS propagation and confirm SSL is active
  9. Have the town manager log in, re-upload budget data, and verify the public portal

Alternative Hosting

Vercel is the path of least resistance, but OpenBook is a standard Next.js app. You can host it anywhere that runs Node.js.

  • Railway (railway.app) — connect your repo, add DATABASE_URL, and Railway handles the rest.
  • Render (render.com) — similar flow. Create a Web Service, point it at your repo, set environment variables.
  • Self-hosted — build and run it yourself:
    npm run build
    npm start

    The app listens on port 3000 by default. Put it behind nginx or Caddy for SSL termination.

Regardless of hosting provider, the same database migration steps apply: switch the Prisma provider to "postgresql", set DATABASE_URL, and run migrations.

Budget Data Format

OpenBook accepts budget data in CSV (.csv) or Excel (.xlsx) format. Upload one file per data category (expenses, revenues, capital).

General Rules

  • Files must have a header row with column names
  • Maximum file size: 10MB
  • Each column must have a unique name
  • Empty rows are automatically skipped
  • Dollar signs, commas, and parentheses in amounts are handled automatically

Amount Columns

OpenBook recognizes fiscal year amounts in column headers:

  • FY2026 Budget
  • FY25 Actual
  • 2026 Appropriation
  • Adopted 2026

Sample: Expenses CSV

Dept,Function,Description,Object Code,FY2024 Actual,FY2025 Budget,FY2026 Budget
Selectmen,General Government,Town Admin Salary,5110,165000,170000,175000
Police,Public Safety,Chief Salary,5110,145000,150000,155000
Police,Public Safety,Patrol Salaries,5110,680000,710000,740000

Sample: Revenues CSV

Category,Source,Description,FY2025 Actual,FY2026 Budget
Tax Levy,Property Tax,Real Estate Tax,28500000,29200000
State Aid,Chapter 70,School Aid,5200000,5350000
Local Receipts,Motor Vehicle,MV Excise,1800000,1850000

Sample: Capital CSV

Department,Purpose,FY2026 Budget,Funding Source
DPW,Road Resurfacing Program,500000,Free Cash
Fire,Engine Replacement,350000,Borrowing
Schools,HVAC Replacement,200000,Capital Stabilization

UMAS (Uniform Municipal Accounting System)

Massachusetts towns report financials using the UMAS format. OpenBook is designed to work with UMAS exports. To upload your UMAS data:

  1. Export your Schedule A data from your accounting system as a CSV or Excel file.
  2. Make sure the export includes column headers (Department, Function Area, Object Code, amounts by fiscal year).
  3. On the upload page, select the matching category (Expenses, Revenues, or Capital).
  4. OpenBook will auto-detect common UMAS header patterns like "FY2026 Budget" and "Object Code".
  5. Review the auto-detected mappings and correct any that look wrong.

UMAS expenditure categories map to OpenBook fields as follows:

UMAS ColumnOpenBook Mapping
Department / DeptDepartment
Function / Functional AreaFunction Area
Object Code / Account CodeAccount / Object Code
Description / Line ItemLine Item / Description
FY20XX Budget / AppropriationFiscal Year Amount (type: Budget)
FY20XX Actual / ExpenditureFiscal Year Amount (type: Actual)

The DOR Schedule A format from the Massachusetts Division of Local Services also works. Export your town's data from the DOR gateway and upload directly.

Common Issues

  • "File has only 1 column" — Your CSV may use semicolons instead of commas. Convert to comma-separated format.
  • "Duplicate column names" — Each column must have a unique header.
  • No fiscal year detected— Include the year in amount column headers (e.g., "FY2026 Budget") or add a separate "Fiscal Year" column.