Everything you need to build websites for clients. One command to set up, interactive wizard to choose your tools.
The easiest way to get started. One command opens a visual interface in your browser where you can pick a folder, name your project, choose your tools, create the project, and start your servers -- all without typing commands.
Step 1. Open your Terminal app. On Mac, press Cmd + Space, type "Terminal", and press Enter.
Step 2. Paste this command and press Enter:
bash <(curl -fsSL https://raw.githubusercontent.com/syedqzaidi/agency-web-stack/main/scripts/launch-ui.sh)Step 3. A browser window opens at http://localhost:3333. You'll see two options:
- Click "New Project" (selected by default)
- Browse and select the folder where you want your project saved
- Type a name for your project
- Pick a preset or choose individual services
- Click "Create Project" and watch the live progress
- Click "Start Astro" or "Start Next.js" to launch your dev servers
- Click the URLs in the table to open your sites
- Click "Open Existing"
- Browse to your previously created project folder
- Click "Select This Project", then "Open Project"
- The GUI auto-detects which services are installed (Astro, Next.js, Supabase, etc.)
- The dashboard appears with dev server controls, service URLs, health status, and validation
- Click "switch project" in the header to go back and open a different project or create a new one
That's it. The GUI handles everything -- downloading, installing, configuring, starting services, and showing you the URLs.
Keep the Terminal window open while using the GUI. If you close it, the GUI stops. To restart it, run the same command again.
If port 3333 is already in use (from a previous session), kill it first:
lsof -ti:3333 | xargs kill -9
bash <(curl -fsSL https://raw.githubusercontent.com/syedqzaidi/agency-web-stack/main/scripts/launch-ui.sh)If you prefer the command line, this single command downloads the template, walks you through a text-based wizard, and sets everything up.
Step 1. Navigate to the folder where you want the project. For example:
cd ~/DesktopStep 2. Run the setup command. Replace my-project with your project name:
curl -fsSL https://raw.githubusercontent.com/syedqzaidi/agency-web-stack/main/scripts/bootstrap.sh | bash -s -- my-projectStep 3. The wizard asks you to pick services using arrow keys and spacebar. When done, it installs everything and starts your services. Takes about 5 minutes.
Step 4. Start your dev servers. Open two terminal windows:
cd ~/Desktop/my-project
pnpm dev:astrocd ~/Desktop/my-project
pnpm dev:nextStep 5. Open the URLs printed in the terminal to see your sites.
To skip the wizard, add a preset:
curl -fsSL https://raw.githubusercontent.com/syedqzaidi/agency-web-stack/main/scripts/bootstrap.sh | bash -s -- my-project --preset=marketingIf you already cloned the repo from the green "Code" button on GitHub:
cd my-project
pnpm install
node scripts/create-project.mjs
./scripts/init-project.sh "my-project"
pnpm dev:astroIMPORTANT: Cloning the repo alone is NOT enough. You must run pnpm install, the wizard, and the init script for anything to work.
| Preset | Best For | What You Get |
|---|---|---|
full |
Everything included | All 14 tools enabled |
marketing |
SEO and marketing websites | Astro + Supabase + Sentry + PostHog |
dashboard |
Admin panels and web apps | Next.js + Payload CMS + Supabase + Sentry |
both-frameworks |
Multi-site projects | Both Astro and Next.js with Supabase and Sentry |
minimal |
Simple static website | Just Astro with Tailwind CSS (no backend) |
nextjs-minimal |
Simple Next.js app | Just Next.js with Tailwind CSS (no backend) |
Use these when you need to manage running services:
| What You Want To Do | Command |
|---|---|
| Launch the GUI (create or reopen projects) | bash <(curl -fsSL https://raw.githubusercontent.com/syedqzaidi/agency-web-stack/main/scripts/launch-ui.sh) |
| Kill the GUI if it won't start | lsof -ti:3333 | xargs kill -9 |
| Kill a stuck Astro server | lsof -ti:PORT | xargs kill -9 (replace PORT with the number shown in .ports) |
| Kill a stuck Next.js server | lsof -ti:PORT | xargs kill -9 (replace PORT with the number shown in .ports) |
| Stop Supabase | pnpm stop:supabase |
| Start Supabase | pnpm dev:supabase |
| Stop Twenty CRM | cd docker/twenty && docker compose down |
| Start Twenty CRM | cd docker/twenty && docker compose up -d |
| Kill everything on a port | lsof -ti:PORT | xargs kill -9 |
| See what is using a port | lsof -i :PORT |
| Check your assigned ports | cat .ports |
Tip: Your project's port numbers are unique and saved in a file called .ports in your project folder. Check that file any time you need to find a URL.
You need these programs installed on your computer before starting. If you used Option A or B above, the bootstrap script will check for these and warn you if anything is missing.
Node.js is the engine that runs JavaScript outside of a web browser. Your website's build tools depend on it.
-
Download from: https://nodejs.org
-
Choose the LTS version (the one labeled "Recommended for Most Users")
-
To check if it is already installed, open Terminal and type:
node --version
You should see something like
v20.x.xor higher.
pnpm is a tool that downloads and manages the libraries your project uses. It is faster and more efficient than the default npm.
-
After installing Node.js, open Terminal and run:
npm install -g pnpm
-
The bootstrap command (Option A/B) will install this automatically if it is missing.
Docker runs small, isolated servers on your computer -- this is how the database, email testing tool, and CRM run locally without you having to install each one separately.
- Download from: https://www.docker.com/products/docker-desktop/
- After installing, open the Docker Desktop app and wait until it says "Running" in the bottom-left corner
- Docker is needed for Supabase (database), Mailpit (test emails), and Twenty CRM
Git is a tool for downloading and tracking changes to code. The bootstrap command uses it behind the scenes.
-
Usually pre-installed on Mac. To check, open Terminal and type:
git --version
-
If not installed, download from: https://git-scm.com
IMPORTANT: Your websites and services will not be accessible until you start the servers. The URLs shown during setup will not load until you complete this step.
The init script (step 4 of setup) starts Docker services automatically -- these are the background services like your database and email inbox. However, the development servers where you actually see your website need to be started separately.
pnpm dev:astropnpm dev:nextOpen two separate Terminal windows. Run one command in each window. Both servers need to stay running while you work.
When a server starts successfully, it prints a URL in the Terminal. Open that URL in your browser to see your website. The URLs look something like this:
http://localhost:4487 (your Astro website)
http://localhost:3187 (your Next.js app)
http://localhost:3187/admin (your CMS admin panel)
Note: The exact port numbers (the numbers after localhost:) are unique to your project. They are randomly assigned during setup so that multiple projects do not conflict. Check the output when you run the start command, or look in the .ports file in your project folder.
After running the init script and starting dev servers, these are the services you can access:
| Service | What It Is | How to Access |
|---|---|---|
| Astro Website | Your marketing or SEO website | Open the URL shown when you run pnpm dev:astro |
| Next.js App | Your dashboard or web application | Open the URL shown when you run pnpm dev:next |
| CMS Admin Panel | Where you manage page content, blog posts, etc. | Go to your Next.js URL and add /admin to the end |
| Supabase Studio | Visual tool for managing your database tables and users | URL shown during setup (usually includes port 54323) |
| Mailpit | A fake email inbox for testing -- emails your app sends appear here | URL shown during setup (usually includes port 54324) |
| Twenty CRM | Customer relationship manager for tracking contacts and deals | URL shown during setup (usually port 3001) |
All URLs are printed at the end of the setup process and saved in a .ports file in your project folder. Open that file any time you need to find a URL.
This template bundles 14 tools so you do not have to find, install, and configure them individually.
| Tool | Version | What It Does | Required? |
|---|---|---|---|
| Astro | 6.1.4 | Builds fast marketing and SEO websites. Great for content-heavy pages | At least one framework required |
| Next.js | 16.2.2 | Builds interactive web apps, dashboards, and admin panels | At least one framework required |
| Payload CMS | 3.81.0 | Content management system -- lets non-developers edit page content through a visual admin panel | Optional (needs Next.js + Supabase) |
| Tailwind CSS | 4.2.2 | A styling system that lets you design pages by adding class names directly in HTML | Included with frameworks |
| shadcn/ui | 4.1.2 | 16 pre-built interface components (buttons, forms, tables, dialogs, etc.) | Included with frameworks |
| Motion | 12.38.0 | Adds animations and transitions to page elements | Included with frameworks |
| Supabase | CLI 2.85 / JS 2.101 | Database, user login/registration, and file storage -- all running locally on your computer | Optional |
| Sentry | 10.47.0 | Catches and reports errors so you know when something breaks | Optional |
| PostHog | 1.364.7 | Tracks how visitors use your website -- page views, clicks, session recordings | Optional |
| Resend | 6.10.0 | Sends real emails (password resets, notifications, etc.) through a simple API | Optional |
| Vercel CLI | 50.40.0 | Deploys your website to the internet with one command | Optional |
| Twenty CRM | 1.20.0 | A customer relationship manager for tracking leads and deals, runs locally via Docker | Optional |
@template/shared |
workspace | Pre-built code for connecting to Supabase, PostHog, and Resend from either framework | Included |
| AI Website Cloner | -- | Tool for cloning and adapting the design of existing websites | Optional |
Each preset is a pre-selected combination of tools. Use them with the --preset= flag to skip the interactive wizard.
| Preset | Command | Frameworks | Backend | Integrations |
|---|---|---|---|---|
full |
--preset=full |
Astro + Next.js | Supabase + Payload CMS + Twenty CRM | Sentry + PostHog + Resend |
marketing |
--preset=marketing |
Astro | Supabase | Sentry + PostHog |
dashboard |
--preset=dashboard |
Next.js | Supabase + Payload CMS | Sentry |
both-frameworks |
--preset=both-frameworks |
Astro + Next.js | Supabase | Sentry |
minimal |
--preset=minimal |
Astro | None | None |
nextjs-minimal |
--preset=nextjs-minimal |
Next.js | None | None |
For advanced users who want full control without the wizard. Combine any of these flags:
Frameworks: --astro, --nextjs
Backend: --supabase, --payload, --twenty
Integrations: --sentry, --posthog, --resend
Options: --all, --name=<name>, --preset=<name>, --no-install, --no-init, --help
Example -- create a project with Astro, Supabase, and Sentry, skipping the wizard:
node scripts/create-project.mjs my-project --astro --supabase --sentrypnpm stop:supabase
cd docker/twenty && docker compose downPress Ctrl+C in the Terminal window where it is running.
You need to open the Terminal app first. On Mac, press Cmd + Space, type "Terminal", and press Enter. Then paste the command.
If curl itself is not found (rare), install the Xcode command line tools:
xcode-select --installYour server is not running. The URLs only work while the server is actively running in a Terminal window.
- Make sure you ran
pnpm dev:astroorpnpm dev:nextand that the Terminal shows it is running - Check that you are using the correct URL -- look at what the Terminal printed when the server started
- If you closed the Terminal window, the server stopped. Open a new Terminal, navigate to your project folder, and start it again
- Open the Docker Desktop application
- Wait until the bottom-left corner says "Running" (this can take 30-60 seconds)
- Try your command again
If Docker Desktop is not installed, download it from https://www.docker.com/products/docker-desktop/
Only one Supabase project can run at a time on your computer. Stop the other one first:
supabase stop --no-backup
pnpm dev:supabaseAnother program is using the same port. Find out what:
lsof -i :<port-number>Either close the conflicting program, or change the port in your project configuration.
- Make sure Supabase is running:
pnpm dev:supabase - Make sure the Next.js server is running:
pnpm dev:next - Visit the admin URL (your Next.js URL +
/admin) to complete first-run setup if you have not already
Run pnpm install from the project root folder (not inside a subfolder). This sets up the internal links between packages.
cd my-project
pnpm installTwenty sometimes fails on first boot. Reset it and try again:
cd docker/twenty
docker compose down -v
docker compose up -d
docker compose logs -f twentyNote: down -v deletes all CRM data. The start_period: 60s health check means Twenty may show as unhealthy for up to a minute while it sets up -- this is normal.
Tailwind CSS v4 does not use a tailwind.config.js file. Check these three things:
@tailwindcss/viteis listed in thepluginsarray inastro.config.mjs- Your global CSS file contains
@import "tailwindcss"; - That CSS file is imported in your layout
If styles still do not appear, clear the cache:
rm -rf templates/astro-site/node_modules/.vite
pnpm dev:astroThis section is for developers who want to understand how the codebase is organized.
agency-web-stack/
├── templates/
│ ├── astro-site/ # Astro marketing/SEO template
│ │ └── src/
│ │ ├── components/ui/ # shadcn/ui components
│ │ ├── layouts/ # Page layout wrappers
│ │ ├── lib/ # Utility functions
│ │ ├── pages/ # Each file becomes a page on your site
│ │ └── styles/ # Global CSS
│ │
│ └── next-app/ # Next.js app/dashboard template
│ └── src/
│ ├── app/
│ │ ├── (app)/ # Your application pages
│ │ ├── (payload)/ # CMS admin panel pages
│ │ └── api/ # Backend API endpoints
│ ├── components/ui/ # shadcn/ui components
│ ├── lib/ # Utility functions
│ └── payload.config.ts
│
├── packages/
│ └── shared/ # @template/shared -- reusable service clients
│ └── src/
│ ├── supabase/ # Database client
│ ├── posthog/ # Analytics client
│ ├── resend/ # Email client
│ └── types/ # Shared TypeScript types
│
├── supabase/
│ ├── config.toml # Local database configuration
│ └── migrations/ # Database schema changes
│
├── docker/
│ └── twenty/
│ ├── docker-compose.yml # Twenty CRM setup
│ └── .env # Twenty CRM secrets
│
├── scripts/ # Setup wizard and init scripts
├── tools/
│ └── ai-website-cloner/ # AI-assisted site cloning tool
├── .env.template # Reference list of all environment variables
├── .mcp.json # AI assistant tool configuration
├── package.json # Project scripts and dependencies
└── pnpm-workspace.yaml # Workspace configuration
Environment variables are settings that your project reads at startup -- things like API keys, database addresses, and secret tokens. The setup wizard fills these in automatically, but you may need to update them later.
The reference file is .env.template in the project root. During setup, .env files are created in each template directory with the correct values.
| Variable | What It Is |
|---|---|
NEXT_PUBLIC_SUPABASE_URL |
Address of your Supabase database. Locally: http://localhost:54321 |
NEXT_PUBLIC_SUPABASE_ANON_KEY |
Public key for browser-side database access (auto-generated) |
SUPABASE_SERVICE_ROLE_KEY |
Private admin key for server-side operations (auto-generated) |
PUBLIC_SUPABASE_URL |
Same as above, for Astro projects |
PUBLIC_SUPABASE_ANON_KEY |
Same as above, for Astro projects |
| Variable | What It Is |
|---|---|
PAYLOAD_SECRET |
Secret key for signing admin tokens (auto-generated) |
DATABASE_URL |
Database connection address. Default: postgresql://postgres:postgres@localhost:54322/postgres |
NEXT_PUBLIC_SERVER_URL |
Your website's public address. Default: http://localhost:3100 |
| Variable | What It Is |
|---|---|
SENTRY_DSN |
Your Sentry project identifier (get from sentry.io) |
NEXT_PUBLIC_SENTRY_DSN |
Same, for browser-side error reporting in Next.js |
PUBLIC_SENTRY_DSN |
Same, for Astro |
SENTRY_AUTH_TOKEN |
Auth token for uploading source maps during builds |
SENTRY_ORG |
Your Sentry organization name |
SENTRY_PROJECT |
Your Sentry project name |
| Variable | What It Is |
|---|---|
NEXT_PUBLIC_POSTHOG_KEY |
Your PostHog project API key (Next.js) |
NEXT_PUBLIC_POSTHOG_HOST |
PostHog server address, e.g. https://us.i.posthog.com |
PUBLIC_POSTHOG_KEY |
Same, for Astro |
PUBLIC_POSTHOG_HOST |
Same, for Astro |
| Variable | What It Is |
|---|---|
RESEND_API_KEY |
API key from resend.com |
| Variable | What It Is |
|---|---|
TWENTY_API_URL |
Address of your Twenty instance. Default: http://localhost:3001 |
TWENTY_API_KEY |
API key from Twenty Settings > API Keys |
Commands you can run from the project root:
| Command | What It Does |
|---|---|
pnpm dev:astro |
Start the Astro website in development mode |
pnpm dev:next |
Start the Next.js app in development mode |
pnpm build:astro |
Build the Astro website for production deployment |
pnpm build:next |
Build the Next.js app for production deployment |
pnpm dev:supabase |
Start the local database and related services |
pnpm stop:supabase |
Stop the local database services |
Commands you can run from inside a template folder (templates/astro-site or templates/next-app):
| Command | What It Does |
|---|---|
pnpm dev |
Start the development server |
pnpm build |
Build for production |
pnpm preview |
Preview the production build locally (Astro only) |
This section covers common tasks once your project is set up.
Both frameworks include shadcn/ui, a library of pre-built interface components. To add a new one:
cd templates/astro-site
pnpm dlx shadcn@latest add accordionOr for Next.js:
cd templates/next-app
pnpm dlx shadcn@latest add accordionComponents appear in src/components/ui/. 16 are pre-installed: avatar, badge, button, card, dialog, dropdown-menu, form, input, label, navigation-menu, separator, sheet, sonner, table, tabs, and field.
Edit templates/next-app/src/payload.config.ts and add to the collections array:
{
slug: "posts",
admin: { useAsTitle: "title" },
fields: [
{ name: "title", type: "text", required: true },
{ name: "content", type: "richText" },
{ name: "publishedAt", type: "date" },
],
}Payload automatically creates the database table and API endpoints when you restart the server.
The @template/shared package provides ready-made clients:
import { createClient } from "@template/shared/supabase";
import { initPostHog } from "@template/shared/posthog";
import { resend } from "@template/shared/resend";- Push your project to a GitHub repository
- Go to vercel.com and create a new project, then import your repository
- Set the Root Directory to
templates/astro-siteortemplates/next-app - Add your environment variables (copy from your
.envfiles but use production values) - Deploy
For Next.js + Payload CMS, also set:
DATABASE_URL-- your Supabase cloud connection stringPAYLOAD_SECRET-- generate a new one withopenssl rand -hex 32NEXT_PUBLIC_SERVER_URL-- your deployed URL, e.g.https://my-project.vercel.app
pnpm supabase link --project-ref <your-project-ref>
pnpm supabase db push- Copy
docker/twenty/docker-compose.ymlanddocker/twenty/.envto your server - Generate a new secret:
openssl rand -hex 32and update.env - Set
SIGN_IN_PREFILLED=falseand updateSERVER_URL/FRONT_BASE_URLto your domain - Run
docker compose up -d
The .mcp.json file includes 10 pre-configured AI tool servers for use with AI coding assistants. These give your AI assistant direct access to documentation and APIs for each service.
| Server | What It Provides |
|---|---|
astro-docs |
Astro documentation search |
next-devtools |
Next.js routes, performance, and build analysis |
shadcn |
Component documentation and examples |
payload |
CMS schema inspection and documentation |
supabase-remote |
Database management and SQL generation |
vercel |
Deployment and domain management |
posthog |
Analytics queries and feature flags |
sentry |
Error search and issue management |
resend |
Email sending and templates |
twenty-crm |
CRM record management |
Servers that need authentication (Supabase, Vercel, PostHog, Sentry, Resend, Twenty) will ask for credentials on first use.
Beyond the external MCP servers above, the Next.js template includes 61 custom MCP tools and 8 prompts built into Payload CMS via @payloadcms/plugin-mcp. These tools let an AI agent manage the entire CMS through conversation.
| Category | Tools | Purpose |
|---|---|---|
| Content Lifecycle | 7 | Publish, unpublish, duplicate, schedule, archive pages |
| SEO Indexing | 10 | Sitemap generation, Google indexing, JSON-LD, hreflang, robots.txt |
| Content Quality | 6 | Word count, readability, orphan pages, thin content, broken links, site health |
| CRO | 3 | Conversion rate optimization analysis |
| i18n | 2 | Translation management |
| Search & Redirects | 3 | Redirect management and search indexing |
| Media | 2 | Image and file management |
| Forms | 2 | Form submission stats and exports |
These automate the pSEO pipeline: seeding data → generating cross-product pages → enriching with AI → validating quality → auditing SEO → managing content lifecycle.
| Category | Tools | File | Purpose |
|---|---|---|---|
| Data Seeding | 5 | pseo-seeding.ts |
Bulk-create services, locations, FAQs, testimonials, team members |
| Page Generation | 3 | pseo-page-generation.ts |
Cross-product service×location pages, AI enrichment, content updates |
| Keywords | 2 | pseo-keywords.ts |
Keyword formula generation, placement validation |
| Quality | 4 | pseo-quality.ts |
Content uniqueness (trigram Jaccard), quality scoring, SEO audit, heading structure |
| Architecture | 4 | pseo-architecture.ts |
Internal linking, orphan detection, slug validation, canonical consistency |
| Lifecycle | 4 | pseo-lifecycle.ts |
Stale page detection, pruning candidates, keyword cannibalization, redirects |
| Local SEO | 4 | pseo-local-seo.ts |
NAP consistency, testimonial coverage, image alt/filename validation |
| Launch | 2 | pseo-launch.ts |
Pre-launch checklist, collection stats dashboard |
| Prompt | Purpose |
|---|---|
brand_voice |
Professional agency tone guidelines |
seo_content_standards |
Meta title/description and keyword placement rules |
landing_page_structure |
Hero → problem → solution → CTA conversion flow |
image_guidelines |
Aspect ratios, alt text rules, format preferences |
translation_guidelines |
SEO-preserving translation with cultural adaptation |
pseo_page_template |
Service-page content templates (headlines, intros, CTAs) |
pseo_enrichment_prompt |
AI enrichment prompt for upgrading template pages |
pseo_launch_readiness |
Pre-launch quality thresholds and readiness checklist |
The MCP plugin exposes these CMS collections with controlled permissions:
| Collection | Find | Create | Update | Delete |
|---|---|---|---|---|
| pages | ✓ | ✓ | ✓ | ✓ |
| media | ✓ | ✓ | ✓ | — |
| users | ✓ | — | — | — |
| services | ✓ | ✓ | ✓ | — |
| locations | ✓ | ✓ | ✓ | — |
| service-pages | ✓ | ✓ | ✓ | ✓ |
| blog-posts | ✓ | ✓ | ✓ | — |
| faqs | ✓ | ✓ | ✓ | ✓ |
| testimonials | ✓ | ✓ | ✓ | — |
| team-members | ✓ | ✓ | ✓ | — |
See templates/next-app/src/mcp/README.md for full tool reference and usage examples.
- Fork the repository and create a feature branch
- Follow the existing code style -- TypeScript, Tailwind CSS v4, no
tailwind.config.js - Test changes against both Astro and Next.js templates where applicable
- Open a pull request describing what you changed and why
MIT -- see LICENSE for details.