Packages
Shared packages for UI components, configuration, TypeScript types, and email templates.
Overview
ScaleRocket uses four shared packages in packages/ that are consumed by all three apps. They are linked via the pnpm workspace -- no publishing or version management needed.
@saas/ui
Location: packages/ui/
The shared component library built with Tailwind CSS. Based on shadcn/ui patterns.
packages/ui/
├── src/
│ ├── components/
│ │ ├── button.tsx
│ │ ├── card.tsx
│ │ ├── input.tsx
│ │ ├── toast.tsx
│ │ ├── theme-provider.tsx
│ │ └── theme-toggle.tsx
│ ├── hooks/
│ │ ├── use-toast.ts
│ │ └── use-theme.ts
│ ├── lib/
│ │ └── utils.ts # cn() utility
│ ├── globals.css # CSS variables, theme
│ └── index.ts # Public exports
├── package.json
└── tsconfig.jsonUsage:
import { Button, Card, Input, useToast, ThemeProvider } from "@saas/ui";cn() utility:
// packages/ui/src/lib/utils.ts
import { clsx, type ClassValue } from "clsx";
import { twMerge } from "tailwind-merge";
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}@saas/config
Location: packages/config/
Centralized configuration shared across all apps.
packages/config/
├── src/
│ ├── site.ts # Site name, URLs, SEO defaults
│ ├── pricing.ts # Plans, prices, Stripe IDs
│ ├── credits.ts # Credit costs per feature
│ └── index.ts # Public exports
├── package.json
└── tsconfig.jsonsite.ts
export const siteConfig = {
name: "ScaleRocket",
description: "Ship your SaaS in days, not months",
url: "https://scalerocket.dev",
appUrl: "https://app.scalerocket.dev",
opsUrl: "https://admin.scalerocket.dev",
ogImage: "https://scalerocket.dev/og.png",
links: {
twitter: "https://twitter.com/scalerocket",
github: "https://github.com/scalerocket",
},
support: {
email: "support@scalerocket.dev",
},
};pricing.ts
export const plans = [
{
id: "starter",
name: "Starter",
price: { monthly: 9, yearly: 90 },
stripePriceId: {
monthly: "price_xxx",
yearly: "price_xxx",
},
credits: 100,
features: ["100 credits/month", "Email support"],
},
// ...more plans
];Usage:
import { siteConfig, plans } from "@saas/config";@saas/types
Location: packages/types/
Shared TypeScript types generated from the database schema and manually maintained API types.
packages/types/
├── src/
│ ├── database.ts # Auto-generated from Supabase
│ ├── api.ts # API request/response types
│ ├── auth.ts # User, session types
│ └── index.ts # Public exports
├── package.json
└── tsconfig.jsondatabase.ts
Auto-generated with:
pnpm supabase gen types typescript --local > packages/types/src/database.tsThis gives you typed queries:
import type { Database } from "@saas/types";
type Profile = Database["public"]["Tables"]["profiles"]["Row"];
type Subscription = Database["public"]["Tables"]["subscriptions"]["Row"];api.ts
Manually maintained types for Edge Function request/response shapes:
export interface CheckoutRequest {
priceId: string;
mode: "subscription" | "payment";
}
export interface CheckoutResponse {
url: string;
}
export interface CreditBalance {
balance: number;
monthly_allowance: number;
last_reset_at: string;
}Usage:
import type { Database, Profile, CheckoutRequest } from "@saas/types";@saas/emails
Location: packages/emails/
React Email templates and a sending utility using Resend.
packages/emails/
├── src/
│ ├── templates/
│ │ ├── welcome.tsx
│ │ ├── password-reset.tsx
│ │ ├── subscription-created.tsx
│ │ └── ...13 templates
│ ├── components/
│ │ └── layout.tsx # Shared email layout
│ ├── send.ts # Resend send utility
│ └── index.ts # Public exports
├── package.json
└── tsconfig.jsonUsage:
import { sendEmail, WelcomeEmail } from "@saas/emails";
await sendEmail({
to: "user@example.com",
subject: "Welcome!",
react: WelcomeEmail({ name: "John", loginUrl: "https://..." }),
});How to Modify a Package
- Edit files in
packages/<name>/src/. - Export new items from
packages/<name>/src/index.ts. - Use them in any app -- the pnpm workspace resolves the link automatically.
- Run
pnpm type-checkto verify nothing is broken.
No build step is needed for development. Turborepo handles builds for production.
How to Add a New Package
# Create the package
mkdir -p packages/analytics/src
cd packages/analytics
# Initialize
pnpm initEdit package.json:
{
"name": "@saas/analytics",
"version": "0.0.0",
"main": "./src/index.ts",
"types": "./src/index.ts",
"scripts": {
"type-check": "tsc --noEmit"
}
}Add it to an app:
pnpm --filter app add @saas/analytics --workspaceImport and use:
import { trackEvent } from "@saas/analytics";Done reading? Mark this page as complete.