Setup Guide
Prerequisites
- Node.js 20 LTS or later
- npm 9+
- A Postgres database connection string
Quick Start
- Clone the repository
git clone https://github.com/your-org/openbook.git cd openbook - Install dependencies
npm install - Set environment variables
cp .env.example .env.local # Edit .env.local with your Postgres DATABASE_URLA local Postgres database works, or you can use a free hosted database from Vercel Storage, Neon, or Supabase.
- Start the development server
npm run devMigrations are applied automatically before the server starts.
First-Time Setup
- Visit
/admin/registerto create an admin account. The first person to register becomes the admin. - Configure your town at
/admin/setup(name, slug, branding). - Upload budget data at
/admin/upload. - Map columns and confirm. Your portal is now live.
Environment Variables
| Variable | Required | Description |
|---|---|---|
DATABASE_URL | Yes | Postgres connection string used by the running app |
DIRECT_URL | No | Direct Postgres connection string for migrations when using pooled databases |
Deployment Guide
OpenBook uses Postgres in local and hosted environments. This section walks through the recommended Vercel deployment 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.
- Fork the repository
Go to
https://github.com/your-org/openbookand click Fork. This gives your town its own copy of the codebase. - 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. - Create a Postgres database
Use Vercel Storage, Neon, or Supabase. Their free tiers are enough for testing one town's budget portal.
- Add environment variables
In the Vercel project settings, go to Environment Variables and add:
Variable Value DATABASE_URLYour Postgres runtime connection string DIRECT_URLOptional direct connection string for migrations If the provider gives you both pooled and direct URLs, use the pooled URL for
DATABASE_URLand the direct URL forDIRECT_URL. - 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.
Custom Domain Setup
Once your portal is deployed, you can point a real domain at it.
- Add the domain in Vercel
Go to your project's Settings → Domains and add your domain (e.g.,
budget.townname.gov). - Add a CNAME record in your DNS provider
Create a CNAME record pointing to:
cname.vercel-dns.comFor
.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. - 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
- Add
DATABASE_URLand, if needed,DIRECT_URLin Vercel - Point the subdomain (e.g.,
budget.townname.gov) via CNAME - Verify the deployment is live and SSL is working
IT Handoff Checklist
- Fork the repo at
https://github.com/your-org/openbook - Create a Vercel account and import the forked repo
- Provision a Postgres database through Vercel Storage, Neon, or Supabase
- Add the runtime connection string as
DATABASE_URLin Vercel environment variables. If the provider gives a direct connection string, add it asDIRECT_URL. - Deploy — Vercel builds automatically on push
- Add custom domain in Vercel and set the CNAME record to
cname.vercel-dns.com - Wait for DNS propagation and confirm SSL is active
- 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, addDATABASE_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 startThe app listens on port 3000 by default. Put it behind nginx or Caddy for SSL termination.
Regardless of hosting provider, set DATABASE_URL before building. The build command runs migrations automatically.
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 BudgetFY25 Actual2026 AppropriationAdopted 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,740000Sample: 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,1850000Sample: 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 StabilizationUMAS (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:
- Export your Schedule A data from your accounting system as a CSV or Excel file.
- Make sure the export includes column headers (Department, Function Area, Object Code, amounts by fiscal year).
- On the upload page, select the matching category (Expenses, Revenues, or Capital).
- OpenBook will auto-detect common UMAS header patterns like "FY2026 Budget" and "Object Code".
- Review the auto-detected mappings and correct any that look wrong.
UMAS expenditure categories map to OpenBook fields as follows:
| UMAS Column | OpenBook Mapping |
|---|---|
| Department / Dept | Department |
| Function / Functional Area | Function Area |
| Object Code / Account Code | Account / Object Code |
| Description / Line Item | Line Item / Description |
| FY20XX Budget / Appropriation | Fiscal Year Amount (type: Budget) |
| FY20XX Actual / Expenditure | Fiscal 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.