@spacemade/ui
v0.0.3
Published
Reusable SaaS bootstrap with optional AI modules.
Readme
App Studio
App Studio is a reusable full-stack SaaS admin starter for building and operating custom products.
By default, the admin app is intended to run under a mounted path such as /admin, while the root / can be served by a separate CMS or public website.
The intended use is:
- start with a real repo, not just a UI kit
- keep a reusable core for auth, users, orgs, billing, settings, and admin
- add your own product-specific models, pages, and workflows on top
- ship with your own containers, pipelines, and deployment flow
- bootstrap new products with
app.sh, install the NPM UI/API packages, then generate app code from an editable schema
This is the right shape for products such as:
- an admin portal
- a site provisioning portal
- a multi-tenant control plane
- a customer success or operations dashboard
- a product that sells plans and manages installations
What App Studio Is
App Studio is a repo-level starter for:
app: React/Next admin UIapi: backend servicedevops: Docker and pipeline setupbilling: Stripe-ready product model patterncore domains: users, orgs, projects, providers, settings, admin
App Studio now supports a hybrid bootstrap model: this repo remains the source foundation, while reusable API/UI pieces can be published as NPM packages and installed into product repos.
Bootstrap With app.sh
For new projects, start with a blank repo and download app.sh into the repo root.
curl -fsSL "$APPSTUDIO_BOOTSTRAP_URL" -o app.sh
chmod +x app.sh
./app.sh init --name my-product
./app.sh edit-schema
./app.sh install
./app.sh generateThe release pipeline publishes the latest script to the application-studio S3 bucket by default:
curl -fsSL "https://s3.amazonaws.com/application-studio/app.sh" -o app.shThe S3 release upload is configured with:
APPSTUDIO_BOOTSTRAP_S3_URI=s3://application-studio/app.shThe bucket or CloudFront distribution should allow public read access to that object. If the bucket still uses object ACLs, set APPSTUDIO_BOOTSTRAP_S3_ACL=public-read; otherwise leave it unset and use a bucket policy. The pipeline also uploads a versioned copy next to it, such as app-0.1.0.sh, unless APPSTUDIO_BOOTSTRAP_S3_VERSION_URI is set.
If you already have app.sh, the local commands are:
./app.sh init --name my-product
./app.sh edit-schema
./app.sh install
./app.sh generateThe intended flow is:
initcreates a lightweight local skeleton andappstudio.schema.json.- You edit the schema for the product shape.
installinstalls the reusable UI and API packages from NPM, or links local checkouts when configured.generatelinks local packages when available, then overlays local routes, models, pages, and module code on top.
The generated repo also gets its own deployable-app scaffold:
bitbucket-pipelines.ymlfor Docker image publish and CloudFormation deploydocker-compose.ymlfor local app/API developmentdevops/docker/Dockerfile.appdevops/docker/Dockerfile.apidevops/cloudformation/app.yml
The default packages are @spacemade/ui and @spacemade/api:
./app.sh installWhen developing the reusable packages and a product app side by side, point the app at the local checkout so imports resolve through node_modules exactly like the published packages:
SPACEMADE_UI_PATH=../appstudio \
SPACEMADE_API_PATH=../appstudio/api \
./app.sh install
./app.sh generate./app.sh link-core ../appstudio also works directly. With no path, it checks common sibling folders such as ../appstudio, ../spacemade-ui, and ../ui.
That creates:
node_modules/@spacemade/ui -> ../appstudio
node_modules/@spacemade/api -> ../appstudio/apiThis is the best local loop because the product app exercises the real package names and package boundaries while still picking up edits from the reusable package checkout immediately.
Repo And NPM Package
Use the repo when you need:
- frontend app structure
- backend API structure
- data model conventions
- Docker and deployment setup
- pipelines
- environment contracts
- product bootstrapping
Use NPM packages for:
- reusable API/UI core
- shared UI components
- shared types and schemas
- Stripe and auth helpers
- the schema-driven generator
Recommended strategy:
- Keep
appstudioas the source repo for the reusable UI, API, and generator. - Publish stable pieces as
@spacemade/*packages. - Build product repos from a blank skeleton using
app.sh. - Let the generator add product-specific modules on top of the installed packages.
For example:
appstudio/ # starter repo
admin-app/ # product repo built from appstudio
@spacemade/ui # reusable admin UI and generator CLI
@spacemade/api # reusable API service
@spacemade/types # shared types
@spacemade/stripe # Stripe helpers
@spacemade/auth # auth helpersBest Fit Product Example
If you are building an Admin portal, appstudio should power:
- account creation and login
- organization and workspace management
- user invites and roles
- pricing and subscriptions
- product instance creation
- install management
- environment and provider configuration
- support/admin operations
Then your product repo adds:
- product-specific models
- site/install lifecycle flows
- domain mapping
- provisioning actions
- template selection
- product management UI
Current Structure
api/
lib/
controllers/
data/
models/
repositories/
services/
pages/api/
devops/
docker/
src/
app/
components/
config/
data/
lib/
types/
docs/
cms-quickstart.md
gallery-quickstart.md
gpu-marketplace-quickstart.md
metaverse-quickstart.md
migration-plan.md
modules.md
nft-quickstart.md
simple-cms-quickstart.md
docker-compose.yml
bitbucket-pipelines.yml
cmd.shMounted Admin App
App Studio is designed to work as an admin application mounted under a subpath.
Examples:
/admin/custom
Recommended deployment shape:
/serves the public CMS or website/adminproxies to the App Studio React app/admin/apior a sibling API hostname proxies to the App Studio API service
Main setting:
NEXT_PUBLIC_APP_BASE_PATH=/admin
This is wired through:
Core Architecture
App Studio should own the reusable SaaS backbone.
Core domains:
- auth
- users
- orgs
- projects
- providers
- pricing
- settings
- admin
Product-specific domains should be added by the product repo.
Examples:
admin-installadmin-templatemanaged-sitemanaged-domainmanaged-modulemanaged-themedeployment-job
How To Build A Custom Product On Top
1. Start With App Studio Core
Keep these areas generic:
- login and session model
- org and membership model
- user roles and admin permissions
- plans and billing entities
- provider registry
- settings pages
- admin shell
2. Add Your Product Domain
For a notepad app, add models such as:
NotebookNoteNoteTagSharedNotePermission
For an Admin portal, add models such as:
AdminInstallAdminTemplateAdminDomainProvisionJobManagedEnvironmentBackupJob
3. Add Product Routes
Examples:
/installs/installs/[id]/templates/domains/deployments
4. Add Product API
Examples:
api/pages/api/installs/index.tsapi/pages/api/installs/[id].tsapi/pages/api/templates/index.tsapi/pages/api/provision/index.ts
5. Add Product Services
Examples:
- install provisioning service
- domain connection service
- deployment orchestration service
- backup and restore service
Backend Pattern
The API follows this structure:
models: domain shapesrepositories: data accessservices: business logiccontrollers: response assemblypages/api: HTTP handlers
Example flow:
HTTP route
-> controller
-> service
-> repository
-> model/dataCurrent reusable examples live in:
Base App Startup
The reusable admin base now includes starter coverage for:
- activity
- addresses
- forms
- invoices
- media
- orgs
- posts
- products
- projects
- providers
- purchases
- sites
- subscriptions
- tags
- tickets
- usage
- users
For database startup in the API service:
- Configure database env vars for
api - Run
npm run migrate:up - Run
npm run seed:up
Reference files:
api/migrations/20260326093000-baseline.jsapi/seeders/20260326094500-base-app.jsapi/doc/migration-baseline.md
Local Docker Dev
App Studio is set up for local containerized development with bind mounts and watch-friendly polling.
Main files:
docker-compose.ymldevops/docker/Dockerfile.appdevops/docker/Dockerfile.apidevops/docker/entrypoint/app-docker-entrypoint.shdevops/docker/entrypoint/api-docker-entrypoint.sh.env
Recommended local flow:
- Configure
.env - Start containers with
docker compose up --build - Open the app on
http://localhost:3000 - Open the API on
http://localhost:3001 - Run
npm run migrate:upandnpm run seed:upinside the API container when ready
Dev-friendly behavior included:
- bind mounts for app and API source
- polling enabled for WSL/docker watch behavior
- named volumes for
node_modulesand.nextcache - API bind mounts for
config,migrations,seeders, andlib - default local auth/session env values for quick access
Important local envs:
NEXT_PUBLIC_APP_BASE_PATHWATCHPACK_POLLING_INTERVALAPI_WATCHPACK_POLLING_INTERVALNEXT_PUBLIC_DEFAULT_USER_IDNEXT_PUBLIC_DEFAULT_ROLENEXT_PUBLIC_DEFAULT_ORG_ROLEDEFAULT_USER_IDDEFAULT_ROLEDEFAULT_ORG_ROLE
Security Layer
App Studio now includes a reusable starter security layer for the admin surface.
Frontend security files:
API security files:
Default behavior:
/and/pricingremain public- core app routes require an authenticated session
adminrequires admin-style access- API domain routes require auth and check CRUD permission by role
Agents
App Studio now includes starter agent scaffolding, but agents are treated as part of the product being built, not tied to a fixed legacy app.
Files:
Use agents for the current product:
- support agents for the admin portal
- publishing agents for the CMS website
- provisioning agents for install systems
- product-specific automation workers
Starter session inputs:
- frontend cookies:
appstudio_user_id,appstudio_role,appstudio_org_role,appstudio_active_org_id,appstudio_active_project_id - API headers:
x-appstudio-user-id,x-appstudio-role,x-appstudio-org-role,x-appstudio-org-id,x-appstudio-project-id - env fallbacks for local setup:
NEXT_PUBLIC_DEFAULT_USER_ID,NEXT_PUBLIC_DEFAULT_ROLE,NEXT_PUBLIC_DEFAULT_ORG_ROLE,DEFAULT_USER_ID,DEFAULT_ROLE,DEFAULT_ORG_ROLE
Frontend Pattern
The frontend should stay focused on:
- dashboards
- settings
- admin workflows
- product configuration
- entity listing/detail pages
The reusable shell lives in:
Stripe Setup
Use Stripe as part of the reusable core, not as product-only code.
Stripe belongs in the platform layer because most admin products need:
- products
- plans
- subscriptions
- invoices
- payment method handling
- entitlement checks
Recommended Stripe Model
Create platform entities like:
BillingProductBillingPlanSubscriptionInvoiceUsageEvent
Then map product-specific entitlements on top:
install_limittemplate_limitcustom_domain_limitbackup_retention_days
Suggested Stripe Flow
- User signs up.
- User creates or joins an org.
- User selects a plan.
- Stripe checkout creates a subscription.
- Webhook updates local subscription state.
- Entitlements unlock product actions.
Stripe Setup In App Studio
Add these areas next:
api/lib/models/billing-*api/lib/services/stripe-service.tsapi/lib/controllers/stripe-controller.tsapi/pages/api/webhook/stripe.tssrc/app/pricingsrc/app/settings/billing
Example Environment Variables
STRIPE_SECRET_KEY=sk_test_xxx
STRIPE_PUBLISHABLE_KEY=pk_test_xxx
STRIPE_WEBHOOK_SECRET=whsec_xxxHandling Users
User handling belongs in core.
Recommended platform user model:
UserUserPasswordor auth provider identityOrgOrgMembershipUserRoleInvite
Recommended roles:
- owner
- admin
- editor
- viewer
For an Admin portal, users should be scoped through org/workspace membership, not just global access.
That gives you:
- multi-tenant separation
- team billing ownership
- shared installations inside an org
- support/admin escalation paths
Admin Portal Design
If the goal is “buy and launch and manage product installs”, your product repo should likely include these domains:
Platform Core
- users
- orgs
- billing
- admin
- providers
- settings
Product Layer
- install catalog
- provisioning jobs
- deployment environments
- connected domains
- backups
- templates
- themes
- plugins/modules
Key Workflows
- Customer signs up.
- Customer picks a plan.
- Customer creates an org/workspace.
- Customer launches an install.
- System provisions the install.
- Customer manages domains, templates, and billing.
- Admin/support can inspect and intervene when needed.
Containers
App Studio includes starter container files:
Current local services:
appapimysql
Start from:
Commands
App Studio includes a repo command wrapper modeled after the parent project:
Examples:
./cmd.sh init cms
./cmd.sh init cms --force
./cmd.sh init simple-cms
./cmd.sh init gallery
./cmd.sh init nft
./cmd.sh init gpu
./cmd.sh init metaverse
./cmd.sh init all --forcePipelines
Bitbucket pipeline file:
Current pipeline shape:
- PR/package verification with
npm pack --dry-run - tag-based publish for
@spacemade/ui - tag-based publish for
@spacemade/api - tag-based upload of
app.shtos3://application-studio/app.sh
Generated product apps should own their Docker images, CloudFormation templates, and runtime deployment pipeline.
Environment Contract
Example frontend/platform config:
NEXT_PUBLIC_APP_NAME=App Studio
NEXT_PUBLIC_ENABLED_MODULES=projects,orgs,providers,users,pricing,settings,adminExample richer product:
NEXT_PUBLIC_APP_NAME=Admin
NEXT_PUBLIC_ENABLED_MODULES=projects,orgs,providers,users,pricing,settings,adminFor an Admin product, avoid turning on AI-style modules unless you actually build them.
Recommended Next Steps
- Add auth and session handling.
- Add org membership and invite models.
- Add Stripe models and webhook handling.
- Add install models.
- Add provisioning job service.
- Add deployment/provider adapters.
- Add admin pages for install lifecycle management.
Practical Recommendation
Use this repo as the source for the reusable @spacemade/ui and @spacemade/api packages.
Build each Admin product as a lightweight repo that installs or links both packages.
Keep product-specific schema, generated overlays, routes, and custom code in the product repo.
If you later discover stable cross-product modules, extract them into additional @spacemade/* packages.
For a CMS-style install system, see:
