<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Drizzle on Producthunt daily</title>
        <link>https://producthunt.programnotes.cn/en/tags/drizzle/</link>
        <description>Recent content in Drizzle on Producthunt daily</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>en</language>
        <lastBuildDate>Sat, 23 Aug 2025 15:26:48 +0800</lastBuildDate><atom:link href="https://producthunt.programnotes.cn/en/tags/drizzle/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>saas-starter</title>
        <link>https://producthunt.programnotes.cn/en/p/saas-starter/</link>
        <pubDate>Sat, 23 Aug 2025 15:26:48 +0800</pubDate>
        
        <guid>https://producthunt.programnotes.cn/en/p/saas-starter/</guid>
        <description>&lt;img src="https://images.unsplash.com/photo-1664366095115-9b4882d0d3b7?ixid=M3w0NjAwMjJ8MHwxfHJhbmRvbXx8fHx8fHx8fDE3NTU5MzM5MjF8&amp;ixlib=rb-4.1.0" alt="Featured image of post saas-starter" /&gt;&lt;h1 id=&#34;nextjssaas-starter&#34;&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/nextjs/saas-starter&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;nextjs/saas-starter&lt;/a&gt;
&lt;/h1&gt;&lt;h1 id=&#34;nextjs-saas-starter&#34;&gt;Next.js SaaS Starter
&lt;/h1&gt;&lt;p&gt;This is a starter template for building a SaaS application using &lt;strong&gt;Next.js&lt;/strong&gt; with support for authentication, Stripe integration for payments, and a dashboard for logged-in users.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Demo: &lt;a class=&#34;link&#34; href=&#34;https://next-saas-start.vercel.app/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://next-saas-start.vercel.app/&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;features&#34;&gt;Features
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Marketing landing page (&lt;code&gt;/&lt;/code&gt;) with animated Terminal element&lt;/li&gt;
&lt;li&gt;Pricing page (&lt;code&gt;/pricing&lt;/code&gt;) which connects to Stripe Checkout&lt;/li&gt;
&lt;li&gt;Dashboard pages with CRUD operations on users/teams&lt;/li&gt;
&lt;li&gt;Basic RBAC with Owner and Member roles&lt;/li&gt;
&lt;li&gt;Subscription management with Stripe Customer Portal&lt;/li&gt;
&lt;li&gt;Email/password authentication with JWTs stored to cookies&lt;/li&gt;
&lt;li&gt;Global middleware to protect logged-in routes&lt;/li&gt;
&lt;li&gt;Local middleware to protect Server Actions or validate Zod schemas&lt;/li&gt;
&lt;li&gt;Activity logging system for any user events&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;tech-stack&#34;&gt;Tech Stack
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Framework&lt;/strong&gt;: &lt;a class=&#34;link&#34; href=&#34;https://nextjs.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Next.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Database&lt;/strong&gt;: &lt;a class=&#34;link&#34; href=&#34;https://www.postgresql.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Postgres&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ORM&lt;/strong&gt;: &lt;a class=&#34;link&#34; href=&#34;https://orm.drizzle.team/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Drizzle&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Payments&lt;/strong&gt;: &lt;a class=&#34;link&#34; href=&#34;https://stripe.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Stripe&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UI Library&lt;/strong&gt;: &lt;a class=&#34;link&#34; href=&#34;https://ui.shadcn.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;shadcn/ui&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;getting-started&#34;&gt;Getting Started
&lt;/h2&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git clone https://github.com/nextjs/saas-starter
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; saas-starter
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pnpm install
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;running-locally&#34;&gt;Running Locally
&lt;/h2&gt;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://docs.stripe.com/stripe-cli&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Install&lt;/a&gt; and log in to your Stripe account:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;stripe login
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Use the included setup script to create your &lt;code&gt;.env&lt;/code&gt; file:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pnpm db:setup
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Run the database migrations and seed the database with a default user and team:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pnpm db:migrate
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pnpm db:seed
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;This will create the following user and team:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;User: &lt;code&gt;test@test.com&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Password: &lt;code&gt;admin123&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can also create new users through the &lt;code&gt;/sign-up&lt;/code&gt; route.&lt;/p&gt;
&lt;p&gt;Finally, run the Next.js development server:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pnpm dev
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Open &lt;a class=&#34;link&#34; href=&#34;http://localhost:3000&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://localhost:3000&lt;/a&gt; in your browser to see the app in action.&lt;/p&gt;
&lt;p&gt;You can listen for Stripe webhooks locally through their CLI to handle subscription change events:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;stripe listen --forward-to localhost:3000/api/stripe/webhook
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;testing-payments&#34;&gt;Testing Payments
&lt;/h2&gt;&lt;p&gt;To test Stripe payments, use the following test card details:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Card Number: &lt;code&gt;4242 4242 4242 4242&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Expiration: Any future date&lt;/li&gt;
&lt;li&gt;CVC: Any 3-digit number&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;going-to-production&#34;&gt;Going to Production
&lt;/h2&gt;&lt;p&gt;When you&amp;rsquo;re ready to deploy your SaaS application to production, follow these steps:&lt;/p&gt;
&lt;h3 id=&#34;set-up-a-production-stripe-webhook&#34;&gt;Set up a production Stripe webhook
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;Go to the Stripe Dashboard and create a new webhook for your production environment.&lt;/li&gt;
&lt;li&gt;Set the endpoint URL to your production API route (e.g., &lt;code&gt;https://yourdomain.com/api/stripe/webhook&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Select the events you want to listen for (e.g., &lt;code&gt;checkout.session.completed&lt;/code&gt;, &lt;code&gt;customer.subscription.updated&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;deploy-to-vercel&#34;&gt;Deploy to Vercel
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;Push your code to a GitHub repository.&lt;/li&gt;
&lt;li&gt;Connect your repository to &lt;a class=&#34;link&#34; href=&#34;https://vercel.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Vercel&lt;/a&gt; and deploy it.&lt;/li&gt;
&lt;li&gt;Follow the Vercel deployment process, which will guide you through setting up your project.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;add-environment-variables&#34;&gt;Add environment variables
&lt;/h3&gt;&lt;p&gt;In your Vercel project settings (or during deployment), add all the necessary environment variables. Make sure to update the values for the production environment, including:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;BASE_URL&lt;/code&gt;: Set this to your production domain.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;STRIPE_SECRET_KEY&lt;/code&gt;: Use your Stripe secret key for the production environment.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;STRIPE_WEBHOOK_SECRET&lt;/code&gt;: Use the webhook secret from the production webhook you created in step 1.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;POSTGRES_URL&lt;/code&gt;: Set this to your production database URL.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AUTH_SECRET&lt;/code&gt;: Set this to a random string. &lt;code&gt;openssl rand -base64 32&lt;/code&gt; will generate one.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;other-templates&#34;&gt;Other Templates
&lt;/h2&gt;&lt;p&gt;While this template is intentionally minimal and to be used as a learning resource, there are other paid versions in the community which are more full-featured:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://achromatic.dev&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://achromatic.dev&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://shipfa.st&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://shipfa.st&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://makerkit.dev&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://makerkit.dev&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://zerotoshipped.com&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://zerotoshipped.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://turbostarter.dev&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://turbostarter.dev&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        
    </channel>
</rss>
