VueLaravelSaaSStarter

saas-starter-laravel — Vue SaaS Template

By kevinmakwana

A multi-tenant SaaS starter template built on Laravel with Inertia + Vue 3 + TypeScript, including teams, roles, invitations, plan limits, a switchable fake payment gateway and Stripe test gateway, and an audit log.

Explore the design

Compare the page layouts and mobile experience. Open any screenshot for a closer look.

1 previews
Author preview
Author-provided preview

Preview provided in the project README.

One original preview is available. Open the full image to inspect the design.

Screenshots show visual appearance; interactive behavior may differ.

Recorded 2026-10-11View source

What stands out

A quick read of the recorded project description.

01

Single-database multi-tenancy: tenant_id plus global scopes isolate reads/writes and route model binding; cross-tenant access returns 404

02

Three roles—Owner, Admin, Member—with policies controlling access to role management, billing, invitations, and audit logs

03

Signed invitation links expire in 7 days, are bound to the invitee's email, are single-use, and emails are sent via a Redis queue

04

Three plans—Free/Pro/Business—with project and member limits enforced in policies and upgrade prompts provided

05

Switchable billing gateway: the default fake gateway requires no paid keys; configure Stripe test keys to enable the Stripe gateway

06

Stripe webhooks verify signatures, deduplicate idempotently by event ID, and process on the webhooks queue

Template Details

This is a multi-tenant SaaS starter template. The backend uses Laravel, the frontend combines Vue 3 and TypeScript via Inertia, and styling is based on Tailwind. It pre-builds common SaaS foundations: registration and login, creating and switching teams, three roles (Owner/Admin/Member) with corresponding policies, signed single-use invitation links that expire in 7 days, three plans (Free/Pro/Business) with project and member count limits, feature flags (e.g., the audit log is available only on Business), and team-scoped audit logs.

The tenant model uses a single-database approach: tenant-owned tables carry tenant_id and are isolated via global scopes. The current tenant is the team the user currently belongs to, and membership is re-validated, so access is revoked immediately after a member is removed; route model binding also goes through this scope, and accessing records from other tenants returns 404.

Billing uses a fake gateway by default, so it runs locally without paid keys; set BILLING_GATEWAY=stripe and provide Stripe test keys to switch to the Stripe gateway. The Stripe webhook endpoint verifies signatures, deduplicates by event ID, and processes on a queue. The README explicitly states that the Stripe path has not been verified in a real Stripe environment, and that the fake gateway and webhook flow have test coverage.

Local operation depends on Docker and make; a single command starts the app, MySQL, Redis, Mailpit, and a queue worker, and runs migrations and seed data; default ports are bound to 127.0.0.1. Tests use Pest, code style uses Pint, static analysis uses Larastan (level 6), the frontend build includes vue-tsc type checking, and CI runs these checks on every push and PR.

VueLaravelSaaSStarter

Is it right for your project?

Use Cases

  • Need to quickly scaffold a multi-tenant SaaS backend skeleton with teams and a role system
  • Want to demonstrate subscription, plan changes, and cancellation flows locally without connecting real payments
  • Need to verify tenant data isolation, invitation flows, plan limits, and webhook idempotency implementation
  • Use as a project reference for learning how Inertia + Vue 3 + TypeScript integrates with Laravel

Suitable For

  • Developers or small teams familiar with Laravel and Vue
  • SaaS projects that need multi-tenancy, role permissions, and subscription billing foundations
  • Teams that want to build on MIT-licensed code for secondary development

Getting started & customization

Use these recorded setup notes alongside the repository instructions for your chosen version.

  1. 1

    Local operation requires Docker and make; running make up starts the app, MySQL 8, Redis, Mailpit, and a queue worker and completes migrations and seed data

  2. 2

    Demo accounts: [email protected] (Owner), [email protected] (Admin), [email protected] (Member); the password for all is password

  3. 3

    If default ports conflict, adjust APP_PORT, FORWARD_DB_PORT, FORWARD_REDIS_PORT, FORWARD_MAILPIT_PORT, FORWARD_MAILPIT_DASHBOARD_PORT, VITE_PORT in .env

  4. 4

    After the first startup, if you change DB_DATABASE or DB_USERNAME, run ./vendor/bin/sail down -v first to let MySQL reinitialize

  5. 5

    To enable real Stripe test mode, set BILLING_GATEWAY=stripe and STRIPE_KEY, STRIPE_SECRET, STRIPE_WEBHOOK_SECRET, STRIPE_PRICE_PRO, STRIPE_PRICE_BUSINESS, and forward events with stripe listen

Read repository instructions

License & source material

Usage conditions & limitations

Free to use · keep license notice

This entry covers the free version in a public repository under the MIT license; the free scope is the code of that version and does not mean external services or third-party assets are free.

Must comply with when using

  • You may use, modify, commercialize, and distribute the code of this version for free.
  • When distributing copies or substantial portions of the code, retain the original author's copyright notice and the full MIT license notice.
  • The code is provided as is; warranties and limitations of liability are governed by the original license and applicable law.

Additional costs & items to verify

  • Demo images, fonts, icons, and other third-party assets must be checked against their respective licenses; they cannot be judged solely by the code's MIT license.
  • External services such as domains, hosting, databases, payments, or AI may incur separate charges.
  • Local operation requires no paid keys and uses the fake payment gateway by default; it switches to the Stripe gateway only when Stripe test keys are provided.
  • Connecting real Stripe test keys is optional; the fake gateway can be used without configuring them.
  • The Stripe payment path has not been verified in a real Stripe environment; only the fake gateway and webhook flow have test coverage and it cannot be considered production-ready.
  • Local operation depends on Docker and the make tool.
  • When enabling Stripe, events must be forwarded to the local webhook endpoint via stripe listen.
  • After the first startup, if you change the database name or username, run sail down -v first to let MySQL reinitialize.
  • All ports are bound only to 127.0.0.1 and are not exposed to the external network by default.
  • The audit log feature is available only on the Business plan.
View Original Text Basis

Permission is hereby granted, free of charge

Original License Text

It runs locally with **zero paid keys**: billing uses a fake gateway unless you add Stripe test keys.

Original README

### Using real Stripe test keys (optional)

Original README

The Stripe path has not been exercised against live Stripe in this repo (see below); the fake gateway and the webhook pipeline are covered by tests.

Original README

Requires Docker (and `make`).

Original README

Forward events with `stripe listen --forward-to localhost:8080/webhooks/stripe`.

Original README

If you change `DB_DATABASE` or `DB_USERNAME` after the first start, run `./vendor/bin/sail down -v` first so MySQL re-initialises.

Original README

All ports bind to `127.0.0.1` only.

Original README

`audit_log` is Business only.

Original README
https://github.com/kevinmakwana/saas-starter-laravel/blob/main/LICENSEhttps://github.com/kevinmakwana/saas-starter-laravel/blob/main/README.md

Compiled by DeepSeek based on repository license and README ·2026-10-11. Results only cover the materials read; dependencies, images, fonts, and subsequent term changes are subject to their respective original texts.

Project checks & description sources

Template Information

Source platforms
GitHub
Documentation and maintenance reference score
Partly documented · 73 / 100
Technologies
Vue · Laravel
Website type
SaaS · Starter
How this score is calculated

Our heuristic uses license records (up to 30), a demo link (12), a preview (10), stars (15), recorded maintenance (15), description completeness (8), feature records (5) and classification data (5). It is not a code, security or performance test, or a Google score. A link does not establish tested functionality.

What to verify for this project

Repository update recorded
2026-10-11
Screenshot last checked
2026-10-11

No demo link is recorded. Use the repository instructions to evaluate the project locally; the screenshot alone cannot establish interactive behavior.

The catalog identifies Vue as the primary stack. Check the actual dependency manifest and lockfile for versions and hosting requirements. These notes use recorded metadata, not a code audit or a deployment test.

Use a selection guide →

How this description was prepared

AI-assisted description based on catalog records and repository material. Repository authors are not automatically the reviewers of this description.

Review declaration: [email protected] · 2026-10-11

Inspect the recorded source material

SHA-256: a411332c2ef2293d3a4863c96dc41e607435f8a778ee773a7cc06526ad5a24d0

2026-10-11T13:27:34.601Z

Source file / repository
# Acme SaaS Starter (Laravel)

A multi-tenant SaaS starter built on Laravel 12, Inertia, Vue 3 and TypeScript.
Teams, roles, signed invitations, plan limits, feature flags and an audit log work out of the box.
It runs locally with **zero paid keys**: billing uses a fake gateway unless you add Stripe test keys.

[![CI](https://github.com/kevinmakwana/saas-starter-laravel/actions/workflows/ci.yml/badge.svg)](https://github.com/kevinmakwana/saas-starter-laravel/actions/workflows/ci.yml)

![Dashboard of the demo team](docs/screenshot.png)

## Quick start

Requires Docker (and `make`). One command starts the app, MySQL 8, Redis, Mailpit and a queue worker, then migrates and seeds:

```bash
make up
```

| What | Where |
| --- | --- |
| App | <http://localhost:8080> |
| Mailpit (all outgoing mail) | <http://localhost:8025> |

**Demo login:** `[email protected]` / `password` (owner of the *Acme Demo* team on the Business plan).
Also seeded with the same password: `[email protected]` (Admin) and `[email protected]` (Member).

Host ports are configurable in `.env` (`APP_PORT`, `FORWARD_DB_PORT`, `FORWARD_REDIS_PORT`,
`FORWARD_MAILPIT_PORT`, `FORWARD_MAILPIT_DASHBOARD_PORT`, `VITE_PORT`) in case the defaults are busy.
All ports bind to `127.0.0.1` only. If you change `DB_DATABASE` or `DB_USERNAME` after the first start, run `./vendor/bin/sail down -v` first so MySQL re-initialises. Other commands: `make dev` (Vite HMR), `make test`, `make fresh`, `make logs`, `make down`.

## How it fits together

```mermaid
flowchart LR
    U[User] -->|current_team_id| T[(Team = tenant)]
    U -->|request| M[EnsureHasTeam middleware]
    M --> C[TenantContext]
    C -->|tenant id| S[TenantScope<br/>global scope]
    S --> P[(projects, tasks,<br/>audit_logs)]
    P -.->|route model binding<br/>goes through the scope| N[404 for other tenants]

    T -->|plan| L[PlanLimits + FeatureGate]
    L -->|402 upgrade prompt| UI[Billing page]
    UI -->|subscribe / change / cancel| G{BillingGateway}
    G -->|no Stripe keys| F[FakeGateway]
    G -->|Stripe test keys| ST[StripeGateway<br/>Cashier 16]
    ST -->|events| W[POST /webhooks/stripe]
    W -->|verify signature| I[(processed_webhook_events<br/>unique event id)]
    I -->|first delivery only| Q[[Redis queue: webhooks]]
    Q --> J[ProcessStripeWebhook] -->|sets plan| T
```

**Tenancy.** One database; tenant-owned tables carry `tenant_id`. The `BelongsToTenant` trait adds a global
scope and refuses writes for any other tenant. The current tenant is the user's current team, and membership
is re-checked, so removing someone from a team cuts access immediately. With no tenant the scope matches nothing.
Route model binding goes through the same scope, so another tenant's record is a plain 404.

## Features

- **Auth and teams:** register, log in, create teams, switch teams (Breeze, Inertia, Vue 3, TypeScript, Tailwind).
- **Roles and policies:** Owner, Admin and Member. Owners manage roles, billing and ownership transfer. Admins invite members and see the audit log.
- **Invitations:** signed, expiring links (7 days), bound to the invited email, single use. Emails are queued on Redis and show up in Mailpit.
- **Billing:** Free, Pro and Business plans (limits and prices in `config/billing.php`). Subscribe, change plan, cancel and resume.
  `FakeGateway` by default, `StripeGateway` (Cashier 16) when `BILLING_GATEWAY=stripe` and Stripe test keys are set.
- **Webhooks:** `POST /webhooks/stripe` verifies the signature, stores each event id once (idempotent) and processes it on the `webhooks` queue.
- **Plan limits:** project and member limits enforced in policies, with a friendly upgrade prompt.
- **Feature flags:** `FeatureGate` and a `feature:` route middleware. For example `audit_log` is Business only.
- **Projects and tasks:** CRUD with search, status filter and pagination.
- **Audit log:** team-scoped "who did what", visible to Owners and Admins on Business.

### Using real Stripe test keys (optional)

```dotenv
BILLING_GATEWAY=stripe
STRIPE_KEY=pk_test_...
STRIPE_SECRET=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...
STRIPE_PRICE_PRO=price_...
STRIPE_PRICE_BUSINESS=price_...
```

Forward events with `stripe listen --forward-to localhost:8080/webhooks/stripe`.
The Stripe path has not been exercised against live Stripe in this repo (see below); the fake gateway and the webhook pipeline are covered by tests.

## Testing and quality

```bash
make test                  # Pest feature + unit tests (inside Sail)
vendor/bin/pint --test     # code style
vendor/bin/phpstan analyse # Larastan, level 6
npm run build              # vue-tsc type check + Vite build
```

Tests cover tenancy isolation (reads, writes, route model binding), role policies, the invitation flow, plan limits,
webhook signature and idempotency, feature gates, and the seeder. CI (GitHub Actions) runs Pint, Larastan and Pest
against a MySQL 8.4 service container on every push and pull request.

## What I'd do next in production

- Add Stripe Checkout and Customer Portal coverage and test the `StripeGateway` against Stripe's test mode in CI.
- Handle dunning: `invoice.payment_failed`, grace periods, and email notices to the owner.
- Move large tenants to per-tenant database or schema isolation if needed, and add DB-level row security as a second line of defence.
- Add rate limiting on invitations and auth, 2FA, and SSO for Business.
- Make audit logs append-only and exportable, with retention rules.
- Observability: structured logs, Sentry, queue and failed-job alerts, Horizon for Redis queues.
- Add seat-based billing and proration instead of fixed per-plan limits.
- Browser end-to-end tests (Playwright) for the main flows, and zero-downtime deploys with migration safety checks.

## License

[MIT](LICENSE) © Kevin Makwana. "Acme" is a fictional brand used for demonstration.
Report a correction

Explore similar templates

Compare previews and descriptions within the same stack and category.

vitesse

vitesse

Vitesse is an opinionated Vite + Vue 3 starter template maintained by antfu-collective, offering file-based routing, component and API auto-import, Pinia, UnoCSS, PWA, i18n, Markdown, vite-ssg, TypeScript, Vitest, and Cypress.

Vue · Starter

vitesse-webext

vitesse-webext

vitesse-webext is a Vite-powered WebExtension starter template using Vue 3 and TypeScript, with built-in popup, options, and content script examples. It targets Chrome and Firefox, integrates webextension-polyfill, webext-bridge, UnoCSS, VueUse, and unplugin tools, and supports hot reload during development.

Vue · Starter

laravel-vue-spa

laravel-vue-spa

A Laravel + Vue SPA starter kit for quickly building a decoupled web application skeleton. It includes login, registration, email verification, and password reset flows, uses JWT for authentication, and integrates Laravel Socialite with GitHub as an example provider.

Vue · Starter

vue3-h5-template

vue3-h5-template

A mobile H5 starter template built on Vue3, Vite, and Vant4, with TypeScript by default and JavaScript and i18n branches.

Vue · Starter

tov-template

tov-template

tov-template is an MIT-licensed Vite + Vue 3 + TypeScript starter maintained by dishait. It bundles file-based routing, layouts, Mock, auto-imports, UnoCSS, Pinia, vue-request, Vitest, i18n, dark mode, Dockerfile, and engineering scripts.

Vue · Starter

shadcn-vue-landing-page

shadcn-vue-landing-page

A Vue + Shadcn-Vue + TypeScript + Tailwind landing page template with sections like Navbar, Hero, Pricing, FAQ, Team, and Contact, plus dark mode and responsive layout.

Vue · Corporate Website