TinyKit Pro Docs
Technical

Development Guide

This guide covers the development workflow, commands, debugging techniques, and best practices for working with TinyKit Pro.

This guide covers the development workflow, commands, debugging techniques, and best practices for working with TinyKit Pro.

Development Commands

Essential Commands

# Development (with Claude Code integration)
bun dev              # Start both frontend (localhost:3000) and Convex backend
bun dev:frontend     # Next.js only with Turbopack
bun dev:backend      # Convex backend only

# Code Quality - MUST pass before completing any task
bun lint             # ESLint check - MUST pass
bun typecheck        # TypeScript check - MUST pass
bun build            # Production build test

Important: Always run bun lint and bun typecheck before completing any task. These must pass with zero errors.

Database Operations

# Database seeding
bun convex:seed         # Full seed (runs init + assets)
bun convex:seed:init    # Initialize basic seed data only
bun convex:seed:assets  # Upload seed assets only
bun convex:reset        # Reset Convex deployment (use with caution)

# Convex management
npx convex dashboard    # Open Convex admin dashboard
npx convex logs         # View function execution logs
npx convex logs --tail  # Stream live logs
npx convex status       # Check deployment status
npx convex codegen      # Regenerate TypeScript types

External Services

# Stripe webhook forwarding (runs automatically with bun dev)
bun dev:stripe          # Forward webhooks to Convex backend

# Stripe testing
stripe logs tail     # View webhook delivery logs
stripe test_clocks advance clock_ID --frozen-time TIMESTAMP # Advance test clock

# Email development
bun dev:email           # Open Resend dashboard

Testing Commands

# Unit Tests
bun test                # Run all unit tests (frontend + backend)
bun test:watch          # Run tests in watch mode
bun test:frontend       # Run React/Next.js frontend unit tests only
bun test:backend        # Run Convex backend unit tests only
bun test:coverage       # Run tests with coverage report

# End-to-End Tests
bun test:e2e            # Run all Playwright E2E tests
bun test:e2e:ui         # Open Playwright UI for debugging

Package Management

# Bun package management (faster than npm/yarn)
bun install          # Install dependencies
bun update           # Update dependencies
bun outdated         # Check for outdated packages
bun add package      # Add new package
bun remove package   # Remove package

Why Bun for Development?

TinyKit Pro is specifically configured to use Bun for optimal Claude Code integration:

Claude Code Integration Benefits

  • 🔍 Real-time Console Visibility: All console.logs and errors from both Next.js frontend and Convex backend appear directly in your terminal
  • 🎨 Color-coded Output: Frontend logs appear in cyan, backend in yellow with clear [frontend]/[backend] prefixes
  • ⚡ Faster Development: Superior performance for installs and updates speeds up development cycles
  • 🛠️ Better Error Tracking: All JavaScript errors, warnings, and console outputs are immediately visible to Claude Code
  • 🔄 Live Development Feedback: Real-time visibility into application behavior without switching between browser DevTools and terminal

Performance Benefits

  • 📦 Lightning Fast Installs: 2-3x faster package installation compared to npm/yarn/pnpm
  • 🚀 Quick Script Execution: Faster script execution for development tasks
  • 💾 Efficient Caching: Smart caching reduces repeated work
  • 🔗 Native TypeScript: Built-in TypeScript support without additional transpilation

Development Workflow

Starting Development

  1. Environment Setup: Ensure .env.local is configured
  2. Start Services: Run bun dev to start full stack
  3. Verify Setup: Check both frontend (3000) and backend are running
  4. Enable Webhooks: Start bun dev:stripe if testing billing

Code Quality Workflow

Always follow this workflow before committing or completing tasks:

# 1. Check code formatting and style
bun lint

# 2. Verify TypeScript compilation
bun typecheck

# 3. Test production build
bun build

# 4. If everything passes, proceed with commit/deployment

Git Workflow

TinyKit Pro uses Husky hooks to enforce branch protection and code quality. The workflow is designed to be flexible for rapid development while maintaining strict protection for production.

Branch Protection Strategy

Main Branch (Strict Protection):

  • ✅ Protected by pre-commit hook - direct commits blocked
  • ✅ Protected by pre-merge-commit hook - local merges blocked
  • ✅ All changes must go through GitHub Pull Requests
  • ✅ Ensures production stability and code review

Develop Branch (Flexible Workflow):

  • ⚡ Direct commits allowed (pre-commit hook disabled)
  • ⚡ Local merges allowed (pre-merge-commit hook disabled)
  • ⚡ Enables rapid iteration and "vibe coding"
  • ⚡ Can be re-enabled for stricter workflow when needed

For Rapid Development (Current Setup):

# Work directly on develop branch
git checkout develop
git pull origin develop

# Make changes and commit
git add .
git commit -m "feat: add new feature"

# Push to remote
git push origin develop

# For merging feature branches
git checkout develop
git merge feature-branch  # Local merge allowed
git push origin develop

For Stricter Workflow (Uncomment Hooks):

# Create feature branch from develop
git checkout develop
git pull origin develop
git checkout -b feature/new-feature

# Make changes and commit
git add .
git commit -m "feat: add new feature"

# Push and create PR
git push origin feature/new-feature
gh pr create --base develop

# After PR approval, merge on GitHub

Enabling Strict Mode

To re-enable strict branch protection for develop:

1. Edit .husky/pre-commit:

# Uncomment these lines:
if [ "$branch" = "develop" ]; then
  echo "🚫 You can't commit directly to develop branch, create a new branch from develop, then commit"
  exit 1
fi

2. Edit .husky/pre-merge-commit:

# Uncomment these lines:
if [ "$target_branch" = "develop" ]; then
  echo "🚫 Local merges into develop branch are not allowed"
  echo "Please create a pull request on GitHub instead"
  exit 1
fi

Pre-Commit Automation

Lint-Staged Integration:

All commits automatically run:

  • Prettier - Auto-formats staged files
  • ESLint - Checks code style and quality
# This happens automatically on git commit
# Configured in package.json:
{
  "lint-staged": {
    "**/*.{js,cjs,mjs,ts,tsx,md,json,sql}": "prettier --write --ignore-unknown"
  }
}

Common Git Tasks

Create and Push Feature:

# Current setup (develop branch)
git add .
git commit -m "feat: add feature name"
git push origin develop

# Strict setup (feature branch)
git checkout -b feature/name
git add .
git commit -m "feat: add feature name"
git push origin feature/name
gh pr create --base develop

View Branch Status:

git status              # Check current changes
git branch -a           # List all branches
git log --oneline -10   # Recent commits

Sync with Remote:

git fetch origin        # Fetch latest changes
git pull origin develop # Pull and merge
git rebase origin/develop # Rebase instead of merge

Feature Development Workflow

1. Backend Development

# Create Convex functions following domain structure
convex/
├── featureName/
   ├── public/
   ├── queries.ts       # Read operations
   ├── mutations.ts     # Write operations
   └── actions.ts       # External API calls
   ├── internal/            # Internal helpers
   ├── helpers.ts           # Domain utilities
   └── schema.ts           # Type definitions

2. Frontend Development

# Create components following established patterns
src/
├── app/
   └── feature/             # Page components
├── components/
   ├── ui/                  # shadcn/ui components
   └── feature/             # Feature-specific components
└── hooks/
    └── useFeature.ts        # Custom hooks

3. Integration Testing

# Test the complete feature
bun dev                      # Start development environment
# Test functionality in browser
bun lint && bun typecheck    # Verify code quality

Debugging Techniques

Backend Debugging

Convex Function Logs

# View all function logs
npx convex logs

# Stream live logs
npx convex logs --tail

# Filter logs by pattern
npx convex logs --tail | grep "error\|warn"

# Filter by specific domain
npx convex logs --tail | grep "billing\|team\|user"

Function Performance

# Monitor function execution time
npx convex dashboard
# Navigate to Functions tab for performance metrics

# Check database query performance
# Look for slow queries in dashboard

Frontend Debugging

Console Output with Claude Code

When using bun dev, all console output appears in your terminal with color coding:

# Frontend logs appear in cyan with [frontend] prefix
[frontend] User login successful
[frontend] Team data loaded

# Backend logs appear in yellow with [backend] prefix
[backend] Processing team invitation
[backend] Email sent successfully

React DevTools

# Install React DevTools browser extension
# Available for Chrome, Firefox, Edge

# Debug component state and props
# Monitor React Query cache
# Inspect component re-renders

Database Debugging

Convex Dashboard

npx convex dashboard

Use the dashboard to:

  • Browse database tables and records
  • Execute queries interactively
  • Monitor function performance
  • View real-time metrics

Query Debugging

// Add logging to functions for debugging
export const debugQuery = query({
  handler: async (ctx, args) => {
    console.log("Query args:", args);

    const result = await ctx.db
      .query("tableName")
      .withIndex("indexName", (q) => q.eq("field", args.value))
      .collect();

    console.log("Query result count:", result.length);
    return result;
  },
});

Integration Debugging

Stripe Integration

# Monitor webhook delivery
stripe logs tail

# Test webhook events
stripe trigger customer.subscription.created

# Check webhook signature issues
# Verify STRIPE_WEBHOOKS_SECRET in environment

Email System

# Check Resend delivery
# Visit resend.com/emails

# View email logs in Convex
npx convex logs --tail | grep "email\|resend"

# Test email templates
cd emails && npx tsx renderTemplate.ts

Code Quality Standards

TypeScript Standards

  • Strict Mode: TypeScript strict mode is enabled
  • No Any Types: Never use any - always find the correct type
  • Generated Types: Use Convex generated types from _generated/
  • Type Imports: Use import type for type-only imports
// Good: Use proper types
import type { Id } from "@/convex/_generated/dataModel";
import { api } from "@/convex/_generated/api";

// Bad: Don't use any
const handleData = (data: any) => {
  /* ... */
};

// Good: Use specific types
const handleData = (data: TeamMember) => {
  /* ... */
};

ESLint Standards

  • All Rules Pass: ESLint must pass with zero warnings/errors
  • Consistent Formatting: Use project ESLint configuration
  • Import Organization: Follow established import ordering
  • Unused Variables: Remove all unused variables and imports

File Organization Standards

Naming Conventions

  • Files: kebab-case (team-settings.tsx)
  • Components: PascalCase (TeamSettings)
  • Functions: camelCase (getUserTeamRole)
  • Constants: UPPER_SNAKE_CASE (STRIPE_PLANS)
  • Types: PascalCase (TeamMember, UserRole)

Import Conventions

// 1. React and external libraries
import React from "react";
import { useQuery, useMutation } from "convex/react";

// 2. Internal utilities and types
import { api } from "@/convex/_generated/api";
import type { Id } from "@/convex/_generated/dataModel";

// 3. Components
import { Button } from "@/components/ui/button";
import { TeamCard } from "@/components/teams/TeamCard";

// 4. Relative imports last
import "./styles.css";

Performance Optimization

Frontend Performance

React Optimization

// Use React.memo for expensive components
const ExpensiveComponent = React.memo(({ data }) => {
  const processedData = useMemo(() => {
    return heavyComputation(data);
  }, [data]);

  return <div>{processedData}</div>;
});

// Implement proper loading states
const { data: teams, isLoading } = useQuery(api.teams.queries.list);

if (isLoading) {
  return <LoadingSkeleton />;
}

Bundle Optimization

# Analyze bundle size
bun build && npx @next/bundle-analyzer

# Monitor for large dependencies
# Use dynamic imports for heavy components
const HeavyComponent = lazy(() => import("./HeavyComponent"));

Backend Performance

Query Optimization

// Good: Use indexes for efficient queries
export const getTeamMessages = query({
  args: { teamId: v.id("teams") },
  handler: async (ctx, args) => {
    return await ctx.db
      .query("messages")
      .withIndex("by_team", (q) => q.eq("teamId", args.teamId))
      .order("desc")
      .take(50);
  },
});

// Bad: Full table scan
export const getTeamMessagesSlow = query({
  handler: async (ctx, args) => {
    const allMessages = await ctx.db.query("messages").collect();
    return allMessages.filter((m) => m.teamId === args.teamId).slice(0, 50);
  },
});

Function Performance

  • Minimize Database Calls: Batch operations when possible
  • Use Appropriate Indexes: Design queries to use existing indexes
  • Implement Pagination: Use cursor-based pagination for large datasets
  • Cache Heavy Computations: Store computed results when appropriate

Testing Strategies

Manual Testing

Feature Testing Checklist

  • Authentication: Sign in/out, OAuth providers, password reset
  • Team Operations: Create, join, leave, role changes
  • Billing Features: Subscribe, upgrade, downgrade, cancel
  • Real-time Updates: Notifications, live data changes
  • Permission System: Role-based access control
  • Email System: Notifications, invitations, billing emails

Cross-browser Testing

  • Chrome: Primary development browser
  • Firefox: Test compatibility
  • Safari: Test WebKit differences
  • Mobile: Test responsive design

Integration Testing

Stripe Integration

# Test subscription flow
1. Create account -> Subscribe -> Check webhook delivery
2. Upgrade plan -> Verify proration -> Check email notifications
3. Cancel subscription -> Verify access changes

# Test with test clocks for accurate proration
stripe test_clocks create --frozen-time $(date +%s)
stripe test_clocks advance clock_ID --frozen-time NEW_TIMESTAMP

Email Testing

# Test notification system
1. Send admin announcement -> Verify in-app + email delivery
2. Invite team member -> Check invitation email and acceptance
3. Billing update -> Verify appropriate email template used

Troubleshooting Guide

Common Development Issues

TypeScript Errors

# Clear Next.js cache
rm -rf .next && bun build

# Regenerate Convex types
npx convex codegen

# Check for version conflicts
bun outdated

Database Issues

# Check Convex connection
npx convex status

# Reset Convex authentication
npx convex logout && npx convex login

# Clear local database (development only)
rm -rf .convex

Performance Issues

# Profile bundle size
bun build && npx @next/bundle-analyzer

# Monitor memory usage
# Use browser DevTools Performance tab

# Check for memory leaks
# Use React DevTools Profiler

Best Practices

Development Best Practices

  1. Start Small: Implement features incrementally
  2. Test Early: Test functionality as you develop
  3. Code Quality: Run lint/typecheck frequently
  4. Documentation: Update docs when adding features
  5. Error Handling: Implement comprehensive error handling

Security Best Practices

  1. Validate Inputs: Both client and server-side validation
  2. Check Permissions: Always verify user permissions
  3. Secure Defaults: Use secure defaults for new features
  4. Environment Variables: Never commit secrets to version control
  5. Regular Updates: Keep dependencies updated for security

Performance Best Practices

  1. Optimize Queries: Use appropriate database indexes
  2. Minimize Re-renders: Use React.memo and useMemo appropriately
  3. Lazy Loading: Load components and data when needed
  4. Bundle Size: Monitor and optimize JavaScript bundle size
  5. Caching: Leverage Convex automatic caching effectively

← Previous: Architecture | Next: Deployment →

On this page

Ship your startup faster. In minutes.

Get TinyKit Pro