Host on a VPS · Cloud hosting · Website on Netlify · Develop locally · Documentation
Space Works Organization is free, open-source membership software from Space Works for clubs, associations, societies and alumni bodies. Publish your plans, take join applications, approve members, collect fees online or by UPI, issue GST-correct receipts and member cards anyone can check with a scan, chase renewals and read the year at a glance, all from one self-hosted app you control. It is built for the secretaries and treasurers who run all of this by hand today, with spreadsheets, UPI screenshots and receipt books, and for Indian organisations first: the April–March year, GST and UPI are built in.
One deployment hosts many organisations. Each owns its plans, members, money and pages, fully isolated
from the others. Organisations apply at /start and a platform admin reviews them, or the platform admin sets
one up and invites its owner. It is part of the Space Works
family.
Status: in active development, phase by phase. See
docs/plans/2026-10-19-membership-rebuild.md.
Grouped the way an organisation's year actually goes.
- Fixed (financial year) or rolling plans with prices in integer paise, joining fees, renewal prices and other currencies.
- A public page per organisation, edited in Settings, with every plan and a Join or Apply to join button.
- Join forms shaped per plan: your own questions (including "choose several", section headings and questions shown only when an earlier answer matches), an optional or required photo, phone and state on or off, open, approval-only or invitation-only, with consent recorded.
- A member register with search, filters (active, waiting, in grace, lapsed, ending soon) and bulk approvals.
- Districts, chapters or branches as units, with managers scoped to their own unit.
- Member roles that print on the card, CSV or Google Sheets import, and an export of everything.
- A membership sweep that moves people through grace and lapse, with renewal reminders by email.
- Razorpay or Stripe on the organisation's own account, or UPI, bank transfer and cash with a UPI QR for the exact amount.
- Maker-checker: a member or one staff member records a payment, another confirms it.
- Gapless receipt numbers per organisation per financial year; tax invoices with CGST and SGST or IGST, bills of supply, and credit notes. Paid rows are never edited, only reversed.
- One card per member and plan, issued when the membership starts, in your colours, with photo and role.
- A verify QR on every card that opens a public check page: Valid, Expired, Revoked or Replaced, read live.
- Scanned outside the app, the page also shows the card itself while the membership is current. Staff who scan it see the member in their own organisation and can verify, renew, record a payment, extend or revoke there.
- PDF and PNG downloads, and bulk exports for printing.
- Members sign in once and see every organisation they belong to: status, history, cards and receipts.
- Pay what is due, renew, update their details, ask for a refund, export their data or ask to be erased.
- Optional per organisation: with Member accounts off, the organisation just keeps records and payments;
"Pay now" emails carry a secure pay link, and card checks on
/verifykeep working.
- A directory of organisations, and a page for each one with its own accent colour, sections and images.
- Membership change, renewal rate, churn, joins and lapses, applications, renewals due, money by plan and GST summaries, for the platform, each organisation and each unit. PDF snapshots and CSV exports.
- A one-line installer, automatic deploys from GitHub Actions, backups, updates and rollback, cloud mode and a Netlify website split. Details below.
Screenshots come from the demo data (npm run db:seed-demo and npm run db:seed-reports); every name, email,
UPI ID and GSTIN in them is made up.
On a 64-bit Linux server (or macOS / Windows with Docker Desktop running), as a user with sudo:
curl -fsSL https://raw.githubusercontent.com/SpaceWorks-Labs/SpaceWorks-Organization/main/install.sh | bashIt asks every question first, shows a summary, and changes nothing until you confirm. Run the same command again later to update, back up, roll back, check health, set up encrypted off-site backups, change settings, harden the server, recover super-admin access, collect a support bundle or uninstall: the whole product runs and is operated on one server. Details, requirements and options follow below.
Everything runs through Docker Compose: PostgreSQL 16, Redis 7 and Silo object storage (the maintained,
S3-compatible fork of the archived MinIO), each speaking TLS signed by the install's own private CA, plus the
migrations, the app, the background worker and beat, scheduled backups and the Caddy web edge. Every application process
runs from one published image, ghcr.io/spaceworks-labs/spaceworks-organization-backend, in a different role.
Before you start, you need:
- a 64-bit (x86_64 or arm64) Linux server (Debian/Ubuntu, Fedora/RHEL/Alma/Rocky, Arch or openSUSE), macOS, or Windows Git Bash/WSL with Docker Desktop;
- on Linux, root or a user with
sudo: the installer installs Docker, Docker Compose and curl after confirmation; curl (or wget) and tar must already exist; - internet access to
github.comandghcr.io, and at least 8 GiB free disk; - for HTTPS, a domain whose DNS points at the server, with ports 80 and 443 open;
- an SMTP relay on a verified sending domain (Brevo, Amazon SES, Postmark…), and the email and password for your super admin (passwords are only ever set on the server, never by email).
All deployment decisions come first, in this order:
- GitHub repository to install and update from (
SpaceWorks-Labs/SpaceWorks-Organization, or your fork). - Website here? Yes (default), or backend only with the website on Netlify (docs/DEPLOYMENT_NETLIFY.md).
- HTTPS: plain HTTP for a LAN or trial (default), automatic HTTPS with Caddy and Let's Encrypt (domain and
certificate email), or an existing reverse proxy forwarding to
127.0.0.1:8080. A Netlify backend requires HTTPS. - Storage: bundled Silo (default), or an external S3-compatible bucket (endpoint, region, bucket, keys).
- Super-admin email and password (asked twice, hidden), then email: sender, SMTP host, port, login and
password. The installer creates the super admin; later password changes happen only on the server with
bash scripts/admin.sh set-password --email …. - Sign-in options besides email and password: Google, Apple, GitHub as a comma list, or none. Google and GitHub ask for their client ID and secret (blank adds them later); Apple is set up in Super admin → Settings.
- Install a GitHub Actions runner on this server for automatic deploys? [y/N] (Linux with systemd only).
Enter accepts each displayed default; invalid answers are asked again. One summary shows every choice, the
services and host actions before Proceed? [Y/n]. Answering no leaves the install directory absent. Secrets
(database, Redis, storage and application keys, including PAYMENT_SECRETS_KEY) are generated, saved in the
install's owner-only .env, and never printed. Production contains no demo or example data.
One command for everyone, forks included. Pass a fork up front to skip the repository question:
curl -fsSL https://raw.githubusercontent.com/SpaceWorks-Labs/SpaceWorks-Organization/main/install.sh | bash -s -- --repo YourName/SpaceWorks-OrganizationA fork must have published a release first (run its Continuous Release workflow on main once) and its
spaceworks-organization-backend package must be public. Run the installer as your normal user (it asks for
sudo when needed and adds you to the docker group), or with curl … | sudo bash to keep the install owned
by root. It installs to /opt/spaceworks-organization; set SWO_DIR on the bash side of the pipe to change
that. bash install.sh --help prints the checklist without changing anything.
Run the same curl command later and an existing install shows a menu:
- Update to the latest release: backs up the database, moves to the newest main release, runs migrations and restarts.
- Back up now: the database, the uploaded files and the settings, into
backups/. - Roll back to the previous release: the release that ran before the last update.
- Check status and health: every service (backend, worker, beat, PostgreSQL, Redis, Silo, Caddy, backups), disk, the newest backups, certificates, the public address and the operator checks.
- Backups: how often the database is backed up and how long dumps stay, an
ageencryption key kept off the server, and nightly encrypted copies to an off-site S3-compatible bucket. - Change settings: the web address, outgoing email or external bucket keys; the previous settings come back automatically if the checks fail.
- Server security: a firewall allowing only SSH, HTTP and HTTPS, automatic security updates and fail2ban.
- Automatic deploys: install or remove the GitHub Actions runner.
- Recover super-admin access: remove a lost authenticator or set a new password, with
scripts/admin.shon the server only (never a reset link). - Support bundle: checks and logs with secrets redacted, in
support/. - Uninstall: keeps the data, secrets and backups unless you type
DELETE DATA.
0 cancels and is the default. On Linux with systemd the installer also schedules a weekly check that renews the internal certificates two
months before they expire. Each option is a script in scripts/ (vps-status.sh, vps-backup-settings.sh…)
you can also run as the install owner; see docs/DEPLOYMENT_VPS.md.
Desktop or local install. From a checkout: bash setup.sh (Linux, macOS, Git Bash) or
powershell -ExecutionPolicy Bypass -File setup.ps1 (Windows with Docker Desktop). Add --build to build the
image from source instead of pulling it.
Every merge to main builds a release: .github/workflows/release.yml runs the tests, publishes the images
and a GitHub release titled Space Works Organization <VERSION> and tagged v<VERSION>-main.<run>.<sha>,
then promotes the images to latest. Pushes to dev publish images tagged dev for staging, never latest.
A runner on your server receives a deploy job after each release and runs the updater locally; nothing is
pushed into the server and no port is opened. Answer yes during setup, or run bash scripts/install-runner.sh
as the install owner (it asks for a short-lived registration token from the repository's
Settings → Actions → Runners). Then add the repository variable SWO_DEPLOY=true, require approval for
fork workflows, and protect main. The deploy job runs:
bash "$SWO_DIR/scripts/update.sh" --force --version <that release>bash scripts/update.sh --force
# Or deploy an exact published main release:
bash scripts/update.sh --force --version 0.8.0-main.42.a1b2c3d4e5f6
# Return to the release that ran before the last update:
bash scripts/update.sh --rollbackThe updater locks, dumps PostgreSQL to backups/pre-update-*.sql.gz, downloads the target release, installs
its host files (keeping the replaced ones in backups/host-config-*), pulls the pinned images, runs
migrations, waits for every service to be healthy, runs the operator checks and records .spaceworks-version.
A failed update restores the previous host files and images automatically. Forward migrations stay applied; to
return the data as well, restore the pre-update dump with bash scripts/restore.sh backups/<dump>.sql.gz.
This repository is public. A self-hosted runner controls Docker, effectively root on the server: require
approval for all external contributors' workflow runs, restrict the runner to this repository, never add
its label to a pull_request workflow, and keep runner auto-updates on. See docs/SECURITY.md.
Run the app, worker and beat on any Docker host with managed PostgreSQL, Redis (TLS), S3/R2 and SMTP:
sudo install -D -m 600 .env.production.example /etc/spaceworks-organization/cloud.env # then fill it in
scripts/spaceworks-compose.sh cloud up -dOr use the Render Blueprint in render.yaml. See docs/DEPLOYMENT_CLOUD.md.
The website can render on Netlify while every database, payment and email operation stays on your server.
Choose "backend only" in the installer, then follow docs/DEPLOYMENT_NETLIFY.md.
The same website also ships as a container, ghcr.io/spaceworks-labs/spaceworks-organization-frontend.
Space Works Organization follows the Space Works design system: Gilroy Light and ExtraBold, pill-shaped controls, one Unbounded phrase or one bold moment per layout, light and dark modes, and reduced motion respected everywhere. The details are in docs/DESIGN.md.
| Colour | Hex | Colour | Hex | ||
|---|---|---|---|---|---|
| Deep Ink | #142C2A |
Citron | #DFFF8F |
||
| Maker Teal | #006E63 |
Sky Blue | #B5CDFF |
||
| Workshop Orange | #FF7447 |
Warm Yellow | #FFD447 |
||
| Warm Cream | #FFF4E8 |
Patch, the Space Works painted wolf, is the friendly face of the product; the box symbol stays the logo.
Patch walks the 404 page, keeps first-time empty lists company, trots while pages load, and sneezes its vote
when an organisation or a member is approved. The README art is drawn by node scripts/generate-readme-art.mjs.
- Deploying on a server (VPS): installer, layout, backups, restore, update and rollback
- Deploying with managed services (cloud)
- Website on Netlify (split hosting)
- Configuration reference: every environment variable
- Architecture and security
- Design, including Patch and every easter egg
- Payments, GST and reports
Node 22 and Docker:
cp .env.example .env
docker compose up -d # PostgreSQL and Redis for development
npm ci
npm run db:migrate
npm run dev # http://localhost:3000npm run lint, npm run typecheck, npm run test:unit and bash scripts/compose-smoke.sh (the bundled stack
end to end) are what CI runs. See CLAUDE.md for conventions.
Copyright © 2026 Space Works.
Space Works Organization is free software under the
GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later). If you run a modified
version for other people over a network, you must offer them its source code too. See NOTICE for
attribution. The fonts in public/brand/fonts and Patch's artwork keep their own terms and are not covered by
the AGPL.












