@bettercone/ui
Getting Started

Installation

Get started with @bettercone/ui in your project

Installation

This guide will help you install and set up @bettercone/ui in your project.

Prerequisites

Before you begin, make sure you have the following:

  • Node.js 18+ - Download
  • A package manager - npm, pnpm, or yarn
  • React 18+ - Works with Next.js, Vite, Remix, or any React framework
  • Better Auth configured - Better Auth docs

@bettercone/ui works with any React framework (Next.js, Vite, Remix) and any Better Auth backend (Convex, Prisma, Supabase, Drizzle, etc.).

Installation

Install @bettercone/ui and its peer dependencies:

pnpm add @bettercone/ui better-auth
npm install @bettercone/ui better-auth
yarn add @bettercone/ui better-auth

Tailwind CSS Setup

@bettercone/ui uses Tailwind CSS. Add the package to your Tailwind config:

tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    './app/**/*.{js,ts,jsx,tsx,mdx}',
    './components/**/*.{js,ts,jsx,tsx,mdx}',
    // Add this line
    './node_modules/@bettercone/ui/**/*.{js,ts,jsx,tsx}',
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}
tailwind.config.js
/** @type {import('tailwindcss').Config} */
export default {
  content: [
    './index.html',
    './src/**/*.{js,ts,jsx,tsx}',
    // Add this line
    './node_modules/@bettercone/ui/**/*.{js,ts,jsx,tsx}',
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}
tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    './app/**/*.{js,ts,jsx,tsx}',
    // Add this line
    './node_modules/@bettercone/ui/**/*.{js,ts,jsx,tsx}',
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}

Better Auth Setup

You need to have Better Auth configured in your project. Here's a minimal example:

lib/auth-client.ts
import { createAuthClient } from "better-auth/react";
import { organizationClient, stripeClient } from "better-auth/client/plugins";

export const authClient = createAuthClient({
  baseURL: process.env.NEXT_PUBLIC_CONVEX_URL!,
  plugins: [
    organizationClient(),
    stripeClient()
  ]
});
lib/auth-client.ts
import { createAuthClient } from "better-auth/react";
import { organizationClient, stripeClient } from "better-auth/client/plugins";

export const authClient = createAuthClient({
  baseURL: process.env.NEXT_PUBLIC_API_URL!,
  plugins: [
    organizationClient(),
    stripeClient()
  ]
});
lib/auth-client.ts
import { createAuthClient } from "better-auth/react";
import { organizationClient, stripeClient } from "better-auth/client/plugins";

export const authClient = createAuthClient({
  baseURL: process.env.NEXT_PUBLIC_SUPABASE_URL!,
  plugins: [
    organizationClient(),
    stripeClient()
  ]
});
lib/auth-client.ts
import { createAuthClient } from "better-auth/react";
import { organizationClient, stripeClient } from "better-auth/client/plugins";

export const authClient = createAuthClient({
  baseURL: process.env.NEXT_PUBLIC_API_URL!,
  plugins: [
    organizationClient(),
    stripeClient()
  ]
});

The Stripe plugin is required for billing components. Organization plugin is required for team components.

Usage

Import and use components:

app/billing/page.tsx
"use client";

import { BillingDashboard } from "@bettercone/ui";
import { authClient } from "@/lib/auth-client";

export default function BillingPage() {
  const handleManageSubscription = async (subscription, organization) => {
    // Create Stripe portal session
    const response = await fetch("/api/billing/portal", {
      method: "POST",
      body: JSON.stringify({ organizationId: organization?.id })
    });
    const { url } = await response.json();
    window.location.href = url;
  };

  return (
    <div className="container mx-auto py-8">
      <BillingDashboard
        authClient={authClient}
        subscriptionCardProps={{
          onManageSubscription: handleManageSubscription
        }}
      />
    </div>
  );
}

Next Steps

Convex

NEXT_PUBLIC_CONVEX_URL=https://your-deployment.convex.cloud CONVEX_DEPLOY_KEY=your-deploy-key

Better Auth

BETTER_AUTH_SECRET=your-secret-key-here BETTER_AUTH_URL=http://localhost:3000

Stripe

STRIPE_SECRET_KEY=sk_test_... NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_... STRIPE_WEBHOOK_SECRET=whsec_...

Resend (Optional - for emails)

RESEND_API_KEY=re_...

GitHub OAuth (Optional)

GITHUB_CLIENT_ID=your-github-client-id GITHUB_CLIENT_SECRET=your-github-client-secret

Google OAuth (Optional)

GOOGLE_CLIENT_ID=your-google-client-id GOOGLE_CLIENT_SECRET=your-google-client-secret


### Generate Better Auth Secret

```bash
openssl rand -base64 32

Get Stripe API Keys

  1. Go to Stripe Dashboard
  2. Copy your Publishable key and Secret key
  3. For webhooks:

Important: Never commit .env.local to version control. It's already in .gitignore.

Step 5: Configure Stripe Products

Update the Stripe price IDs in packages/convex/convex/subscriptionPlans.ts:

packages/convex/convex/subscriptionPlans.ts
export const subscriptionPlans = [
  {
    id: "free",
    name: "Free",
    price: 0,
    interval: "month" as const,
    stripePriceId: null, // Free tier has no Stripe price
    limits: {
      apiCalls: 10000,
      // ... other limits
    },
  },
  {
    id: "pro",
    name: "Pro",
    price: 29,
    interval: "month" as const,
    stripePriceId: "price_YOUR_PRO_PRICE_ID", // Replace with your Stripe price ID
    limits: {
      apiCalls: 100000,
      // ... other limits
    },
  },
  // ... more plans
];

Create Stripe Products

  1. Go to Stripe Products
  2. Create products for each plan (Pro, Team, etc.)
  3. Create prices for each product
  4. Copy the price IDs and update subscriptionPlans.ts

Step 6: Start Development Server

Return to the root directory and start the development server:

cd ../..
pnpm dev

This will start:

Step 7: Verify Installation

  1. Open http://localhost:3000 in your browser
  2. You should see the BetterCone homepage
  3. Try signing up with email/password
  4. Check that the demo pages work:
    • /demo/account - User profile
    • /demo/billing - Billing dashboard
    • /demo/organization - Team management

Success! If you can sign up and access the demo pages, your installation is complete.

Troubleshooting

Convex connection errors

Problem: ConvexError: Could not reach Convex backend

Solution:

  1. Make sure Convex dev server is running: cd packages/convex && pnpm convex dev
  2. Verify NEXT_PUBLIC_CONVEX_URL in .env.local is correct
  3. Check that you're not behind a firewall blocking Convex

Stripe webhook errors

Problem: Stripe webhooks not working in development

Solution:

  1. Install Stripe CLI: brew install stripe/stripe-cli/stripe
  2. Login: stripe login
  3. Forward webhooks: stripe listen --forward-to localhost:3000/api/webhooks/stripe
  4. Copy the webhook signing secret to STRIPE_WEBHOOK_SECRET

Better Auth errors

Problem: Invalid session or auth not working

Solution:

  1. Verify BETTER_AUTH_SECRET is set (32 character string)
  2. Make sure BETTER_AUTH_URL matches your dev server URL
  3. Clear browser cookies and try again

Build errors

Problem: TypeScript errors or build failures

Solution:

# Clean everything and reinstall
rm -rf node_modules pnpm-lock.yaml
rm -rf apps/web/.next
rm -rf apps/web/node_modules
pnpm install

Next Steps

Now that BetterCone is installed, you can:

Need Help?