Open-source captive breeding and botanical collection management for zoos, aquariums, and botanical gardens.
OpenStudbook is a self-hosted web platform for managing captive animal and plant populations. Track individuals, species, breeding events, genetic lineage, health records, and enclosures — with a global network map for inter-organisation partnerships.
Key features:
- 🐾 Fauna & Flora modes — unified management for animals and plants
- 🧬 Studbook & genetics — lineage tracking, breeding recommendations, DNA records
- 🌍 Network map — discover partner organisations and propose breeding loans
- 🔒 Multi-factor auth, per-org user roles, and full data export
- 🌐 Multi-language — 10 languages, switchable per user
- Requirements
- Quick Start
- Configuration
- Running the Dev Environment
- First-Time Setup (Installer)
- Production Deployment
- Resetting the Database
- Optional: Cloudflare / ngrok Tunnel
- Security
- Contributing
- License
| Dependency | Minimum version | Notes |
|---|---|---|
| Node.js | 18 LTS | 20 LTS recommended |
| npm | 9+ | Bundled with Node |
| MariaDB or MySQL | MariaDB 10.6+ / MySQL 8.0+ | Must support utf8mb4 |
Windows users: MariaDB MSI installer is the easiest option.
macOS users:brew install mariadb && brew services start mariadb
Linux users:sudo apt install mariadb-serveror equivalent.
# 1. Clone
git clone https://github.com/teruselearning/openstud.git
cd openstud
# 2. Install frontend dependencies
npm install
# 3. Install backend dependencies
cd backend && npm install && cd ..
# 4. Configure environment
cp backend/.env.example backend/.env
# → open backend/.env and fill in your DB credentials and JWT secret
# 5. Create the database
# (MariaDB / MySQL must be running)
mysql -u root -p -e "CREATE DATABASE openstudbook CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
# 6. Start the backend
cd backend && npm run dev &
# 7. Start the frontend (new terminal)
npm run devThen open http://localhost:3000 — the installer wizard will guide you through creating your first organisation and admin account.
All backend configuration lives in backend/.env. Copy the example file and edit it:
cp backend/.env.example backend/.env| Variable | Required | Description |
|---|---|---|
PORT |
No | Backend port (default: 3001) |
JWT_SECRET |
Yes | Long random string used to sign auth tokens. Generate one: node -e "console.log(require('crypto').randomBytes(32).toString('hex'))" |
DATABASE_HOST |
Yes | DB host (usually localhost) |
DATABASE_PORT |
No | DB port (default: 3306) |
DATABASE_USER |
Yes | DB username |
DATABASE_PASSWORD |
Yes | DB password |
DATABASE_NAME |
Yes | DB name (e.g. openstudbook) |
Never commit
backend/.env— it is gitignored by default.
You need four processes running simultaneously. Open a separate terminal for each:
cd backend
npm run dev
# Listening on http://localhost:3001npm run dev
# Listening on http://localhost:3000OpenStudbook sends transactional emails (invitations, password reset, MFA codes). In development, catch them locally instead of sending to real inboxes.
Using maildev (recommended):
# Install once
npm install -g maildev
# Run
maildev --smtp 1025 --web 1080Web UI → http://localhost:1080
Then set these values in the Super Admin → SMTP settings panel:
| Setting | Value |
|---|---|
| SMTP Host | localhost |
| SMTP Port | 1025 |
| SMTP User | (empty) |
| SMTP Pass | (empty) |
| Secure (TLS) | Off |
Useful for testing on mobile devices or sharing a preview.
npm run tunnelThe public trycloudflare.com URL is printed to the console. Requires cloudflared installed at C:\Program Files (x86)\cloudflared\cloudflared.exe.
On a fresh database, the app automatically shows the installation wizard at http://localhost:3000.
The wizard will ask you to:
- Test the database connection — verifies the credentials in
backend/.envare working - Create your organisation — name and admin account details
- Choose a focus — Fauna (animals) or Flora (plants)
After setup, you can configure SMTP, languages, branding, and feature flags under Super Admin (the gear icon in the sidebar).
If you need to re-run the installer (e.g. for testing), see Resetting the Database.
OpenStudbook is designed to run on a single Linux/Windows server behind a reverse proxy.
Internet → Nginx (HTTPS/TLS) → Vite static build (port 80)
→ Express backend (port 3001)
# Build the frontend
npm run build
# Output is in dist/ — serve as static files via Nginx
# Build the backend
cd backend && npm run build
# Output is in backend/dist/ — run with: node dist/index.jsserver {
listen 443 ssl;
server_name yourdomain.com;
# SSL cert (e.g. Let's Encrypt)
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
# Frontend (built static files)
root /var/www/openstudbook/dist;
index index.html;
try_files $uri $uri/ /index.html;
# Backend API proxy
location /api/ {
proxy_pass http://localhost:3001;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /rest/ {
proxy_pass http://localhost:3001;
}
location /uploads/ {
proxy_pass http://localhost:3001;
}
}
# Redirect HTTP → HTTPS
server {
listen 80;
server_name yourdomain.com;
return 301 https://$host$request_uri;
}Update backend/.env for production:
NODE_ENV=production
PORT=3001
JWT_SECRET=<strong random secret — rotate quarterly>
DATABASE_HOST=localhost
DATABASE_USER=openstudbook_user
DATABASE_PASSWORD=<strong password>
DATABASE_NAME=openstudbook
# Install pm2
npm install -g pm2
# Start backend
pm2 start backend/dist/index.js --name openstudbook-api
# Auto-restart on reboot
pm2 startup
pm2 save- Lock CORS in
backend/src/index.ts: changeorigin: '*'to your domain - Add
helmetmiddleware:npm install helmet→app.use(helmet()) - Add rate limiting on auth endpoints:
npm install express-rate-limit - Use a strong, unique
JWT_SECRET(32+ random characters) - Restrict DB user permissions — grant only
SELECT, INSERT, UPDATE, DELETEonopenstudbook - Enable HTTPS — use Let's Encrypt / Certbot
- Disable
enableRegistrationin Super Admin if you don't want public sign-ups
Useful during development or to re-run the installer wizard.
MariaDB / MySQL:
mysql -u root -p -e "DROP DATABASE openstudbook; CREATE DATABASE openstudbook CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"Then restart the backend — it will re-run migrations and show the installer on next page load.
Expose your local dev instance publicly (useful for mobile testing, demos, or webhook testing).
Cloudflare Quick Tunnel (no account needed):
npm run tunnelngrok (requires free account):
npm run ngrokBoth print a public HTTPS URL to the console.
The production checklist above covers the essential hardening steps. For ongoing maintenance:
- Rotate
JWT_SECRETandDATABASE_PASSWORDquarterly - Run
npm auditin both root andbackend/regularly — fix anything at high or critical severity - Review and merge Dependabot PRs promptly
- Audit Super Admin accounts periodically — remove any that are no longer needed
To report a vulnerability, please open a GitHub Security Advisory rather than a public issue.
Contributions are welcome! Please:
- Fork the repo and create a feature branch from
main - Run
npm auditin both root andbackend/— no new high/critical issues - Test the installer flow on a fresh database before submitting
- Open a pull request against
mainwith a clear description of the change
For larger changes, open an issue first to discuss the approach.
MIT © OpenStudbook Contributors — see LICENSE.