Follow this guide to quickly build a SaaS MVP in a few days with SaasRock.
SaasRock is more than a boilerplate, it's a SaaS Building Framework. Follow these steps to launch a SaaS MVP in less than a week (or watch me build one in 3 days).
Clone the saasrock repo and set up the upstream for updates.
Initialize git and deploy to a new GitHub repository.
Duplicate .env.example
, rename it to .env
, and set your variables (APP_NAME
, DOMAIN_NAME
, and DATABASE_URL
).
Run npx prisma db push
, and npx prisma db seed
to prepare your local database.
Run npm run dev
, and visit your app at localhost:3000
.
Think of the most important feature.
Create a module under at app/modules/{yourFeature}
with the following files:
.../components
- Lists, Forms, Badges...
.../db
- Custom database models for this feature.
.../dtos
- Data transfer objects.
.../services
- Server-side logic.
.../utils
- Client & Server-side helper functions.
Create the routes under the app.$tenant
directory using this module.
Set up your default plans and feature limits at plans.server.ts
. Preview them at /pricing.
Create a Stripe account and set the STRIPE_SK
environment variable.
Go to /admin/settings/pricing
and click "Click here to generate plans".
Create a test account at /register
or /pricing
.
Create a Postmark account and grab your server token.
Set the POSTMARK_SERVER_TOKEN
and POSTMARK_FROM_EMAIL
env variables.
Go to /admin/settings/transactional-emails
and click "Create all".
Open locale/i18n.ts
, set the languages in supportedLngs
, and the fallbackLng
.
Visit the landing page and test it by adding ?lng=en
or ?lng=yourLocale
to the URL.
Update the theme color by setting the color inside colors { theme: {
.
Replace the logo and icon files under app/assets/img/
: icon-dark.png
, icon-light.png
, logo-dark.png
, logo-light.png
.
Generate your favicon files, and add them under public/
.
app/modules/pageBlocks/utils/defaultPages/defaultLandingPage.ts
to set up your landing page blocks.You have two options to receive submissions:
Create a Formspree form, and set the INTEGRATIONS_CONTACT_FORMSPREE
env variable.
Or go to /admin/entities/templates/manual
, click "Default: CRM", and create them. Contact submissions will be at /admin/crm/submissions
.
Similarly, you have two options to get newsletter subscribers:
Create a Convertkit form, and set the CONVERTKIT_APIKEY
and CONVERTKIT_FORM
variables.
Or use the CRM entities, your newsletter subscribers will be at /admin/crm/contacts?marketingSubscriber=true
.
Go to /admin/blog/new
and write your first blog post.
All your posts will be available at /blog
.
Create as many knowledge bases as you need at /admin/knowledge-base
.
You can use the slugs /docs
or /help/{customSlug}
.
Create a Supabase project and set the SUPABASE_API_URL
and SUPABASE_KEY
environment variables.
Set your DATABASE_URL
variable to use the production database for a moment, run npx prisma db push
, and seed your database with npx prisma db seed
. Important: When seeding a production database, go to app/utils/db/seed/SeedService.ts
and change the default email and password (default is admin@email.com). Once you've successfully seeded the database, change the DATABASE_URL
back to your local database.
To deploy on Fly.io, open fly.toml
and set your app
name, and its primary_region
. Important: The region must match the one used in your database provider (in this case supabase).
Create the app using fly CLI: fly apps create YOUR_APP_NAME
.
Set your secrets: You can see the examples at .env.fly.example
. Important: Use a live STRIPE_SK
key to create live plans, and change other important secrets such as SESSION_SECRET
, JWT_SECRET
and CRYPTO_SECRET
(you can use random values for these three).
Deploy: fly deploy --remote-only
.
Scale (recommended): fly scale vm shared-cpu-2x --app YOUR_APP_NAME
.
Your app should be deployed under a fly.dev
domain, similar to https://saasrock.fly.dev. Use this URL to set SERVER_URL
in the production secrets, and do the same for DOMAIN_NAME
(in this case: saasrock.fly.dev).
Custom domain
Run the following command to get the IPv4 and IPv6 addresses:
flyctl ips list -a YOUR_APP_NAME
Head over to your DNS provider and add A and AAAA records for example.com with the IPv4 and IPv6 values.
Now you can create a certificate for your custom domain:
flyctl certs create -a custom-quartz example.com
Your app should be available at your domain. It may take a few minutes for the certificate to be issued.
/admin/analytics/overview
to analyze your traffic.