Skip to main content

Contributing to Uxie

Thank you for your interest in contributing to Uxie! This guide will help you set up your development environment and understand our development workflow.

Prerequisites

Before you begin, ensure you have the following installed:
1

Node.js v18+

Download from nodejs.org
node --version  # Should be v18.16.0 or higher
2

pnpm Package Manager

Install pnpm globally:
npm install -g [email protected]
Or use Corepack (recommended):
corepack enable
corepack prepare [email protected] --activate
3

Git

For cloning the repository and version control.

Getting Started

1. Fork and Clone

1

Fork the Repository

Visit github.com/zeus-12/uxie and click the “Fork” button to create your own copy.
2

Clone Your Fork

git clone https://github.com/YOUR_USERNAME/uxie.git
cd uxie
3

Add Upstream Remote

git remote add upstream https://github.com/zeus-12/uxie.git
This allows you to pull updates from the main repository.

2. Install Dependencies

pnpm install
This will:
  • Install all npm dependencies
  • Apply patches to react-pdf-highlighter
  • Generate Prisma Client types

3. Set Up Environment Variables

Copy the example environment file:
cp .env.example .env
Now configure each service:
  1. Go to supabase.com and create a new project
  2. Once created, navigate to Settings → Database
  3. Copy the connection string and add to .env:
DATABASE_URL="postgresql://postgres:[PASSWORD]@[HOST]:[PORT]/postgres"
  1. Run migrations:
pnpm prisma db push
  1. Go to Google Cloud Console
  2. Create a new project (or select existing)
  3. Navigate to APIs & Services → Credentials
  4. Click Create Credentials → OAuth 2.0 Client ID
  5. Configure consent screen if prompted
  6. Set Authorized redirect URIs:
    • http://localhost:3000/api/auth/callback/google
  7. Copy credentials to .env:
GOOGLE_CLIENT_ID="your-client-id.apps.googleusercontent.com"
GOOGLE_CLIENT_SECRET="your-client-secret"
  1. Generate NextAuth secret:
openssl rand -base64 32
Add to .env:
NEXTAUTH_SECRET="generated-secret"
NEXTAUTH_URL="http://localhost:3000"
  1. Go to uploadthing.com and sign up
  2. Create a new app
  3. Copy your API token:
UPLOADTHING_TOKEN="your-token"
  1. Go to pinecone.io and sign up
  2. Create a new index with:
    • Name: uxie
    • Dimensions: 768
    • Metric: cosine
    • Region: Choose closest to you
  3. Copy your API key:
PINECONE_API_KEY="your-api-key"
PINECONE_ENVIRONMENT="your-environment"  # e.g., us-east-1
HuggingFace (Embeddings)
  1. Sign up at huggingface.co
  2. Go to Settings → Access Tokens
  3. Create a new token:
HUGGINGFACE_API_KEY="hf_..."
Google AI (Gemini)
  1. Go to ai.google.dev
  2. Get an API key
  3. Add to .env:
GOOGLE_GENERATIVE_AI_API_KEY="your-api-key"
Currently disabled in production due to free tier limits, but you can enable locally:
  1. Go to liveblocks.io and sign up
  2. Create a new project
  3. Copy your public API key:
NEXT_PUBLIC_LIVEBLOCKS_PUBLIC_API_KEY="pk_..."

4. Start Development Server

pnpm dev
The app will be available at http://localhost:3000

Development Workflow

Creating a New Branch

Always create a new branch for your changes:
git checkout -b feature/your-feature-name
Or for bug fixes:
git checkout -b fix/bug-description

Making Changes

1

Write Code

Make your changes following our coding standards (see below).
2

Test Locally

Ensure your changes work:
pnpm dev
3

Type Check

Verify TypeScript types:
pnpm typecheck
4

Lint

Check code quality:
pnpm lint
5

Format

Format code with Prettier:
pnpm format

Committing Changes

We follow conventional commit messages:
git add .
git commit -m "feat: add PDF thumbnail preview"
Commit Types:
TypeDescriptionExample
featNew featurefeat: add export to markdown
fixBug fixfix: resolve highlight position offset
docsDocumentationdocs: update contributing guide
styleCode style (no logic change)style: format with prettier
refactorCode refactoringrefactor: extract PDF utils
perfPerformance improvementperf: optimize vector search
testAdd/update teststest: add flashcard tests
choreMaintenancechore: update dependencies

Opening a Pull Request

1

Push to Your Fork

git push origin feature/your-feature-name
2

Create Pull Request

  1. Go to github.com/zeus-12/uxie
  2. Click “Compare & pull request”
  3. Fill in the PR template
  4. Link any related issues
3

Review Process

  • Maintainers will review your PR
  • Address any feedback
  • Once approved, your PR will be merged!

Coding Standards

TypeScript

Strict Mode

Always use TypeScript in strict mode.
  • No any types (use unknown)
  • Explicit return types for functions
  • Null checks required

Type Inference

Prefer type inference when obvious:
// Good
const count = 5;

// Unnecessary
const count: number = 5;

React Components

Prefer Function Components:
// ✅ Good
export function MyComponent({ title }: { title: string }) {
  return <h1>{title}</h1>;
}

// ❌ Avoid
export const MyComponent: React.FC<{ title: string }> = ({ title }) => {
  return <h1>{title}</h1>;
};
Use Semantic JSX:
// ✅ Good
<button type="button" onClick={handleClick}>
  Click me
</button>

// ❌ Avoid
<div onClick={handleClick}>Click me</div>

File Organization

1

Component Structure

components/
├── feature-name/
│   ├── index.tsx          # Main component
│   ├── sub-component.tsx  # Related components
│   └── utils.ts           # Helper functions
2

Import Order

Prettier will auto-sort, but follow this pattern:
  1. React imports
  2. Third-party libraries
  3. Internal utilities
  4. Types
  5. Styles
3

Naming Conventions

  • Components: PascalCase (PdfReader.tsx)
  • Utilities: camelCase (formatDate.ts)
  • Constants: UPPER_SNAKE_CASE
  • Types/Interfaces: PascalCase

tRPC Procedures

Input Validation:
import { z } from "zod";

export const documentRouter = createTRPCRouter({
  getById: protectedProcedure
    .input(z.object({ id: z.string() }))
    .query(async ({ ctx, input }) => {
      return await ctx.prisma.document.findUnique({
        where: { id: input.id },
      });
    }),
});
Always use protected procedures for authenticated routes.

Prisma Schema

When modifying schema.prisma:
  1. Make changes
  2. Generate migration:
    pnpm prisma migrate dev --name describe_change
    
  3. Generate client:
    pnpm prisma generate
    

Tailwind CSS

Use utility classes:
// ✅ Good
<div className="flex items-center gap-4 rounded-lg bg-white p-4">

// ❌ Avoid custom CSS
<div className="my-custom-class">
Use cn() helper for conditional classes:
import { cn } from "@/lib/utils";

<div className={cn(
  "base-classes",
  isActive && "active-classes",
  className  // Allow external classes
)} />

Testing Locally

Manual Testing Checklist

Before submitting a PR, test:
  • Can sign in with Google
  • Can sign out
  • Protected routes redirect to login
  • Can upload PDF
  • Can view PDF in reader
  • Can add highlights
  • Can add notes
  • Chat works and streams responses
  • Flashcard generation works
  • Flashcard evaluation works

Database Inspection

Use Prisma Studio to inspect database:
pnpm prisma studio
Opens at http://localhost:5555

Common Issues

If port 3000 is taken:
# Kill process on port 3000
lsof -ti:3000 | xargs kill

# Or use different port
PORT=3001 pnpm dev
If you see Prisma import errors:
pnpm prisma generate
This regenerates the Prisma Client.
After pulling latest changes:
pnpm install  # Install new dependencies
pnpm prisma generate  # Regenerate Prisma types
Ensure .env is in root directory (same level as package.json).Restart dev server after changing .env.

Project Scripts

CommandDescription
pnpm devStart development server
pnpm buildBuild for production
pnpm startStart production server
pnpm lintRun ESLint
pnpm typecheckCheck TypeScript types
pnpm formatFormat code with Prettier
pnpm prisma studioOpen Prisma Studio
pnpm prisma migrate devCreate/apply migration
pnpm prisma db pushPush schema without migration

Areas for Contribution

Looking for where to help? Check these areas:

Bug Fixes

  • Fix .tippy-arrow appearing on screen
  • Improve error and loading pages
  • Fix highlight positioning issues

Features

  • Build category/tags system
  • Implement rate limiting with Redis
  • Semantic search improvements
  • PDF summary generation

Performance

  • Optimize PDF rendering
  • Reduce bundle size
  • Improve vector search speed

Documentation

  • Add JSDoc comments
  • Write component docs
  • Create user guides

Code Review Guidelines

When reviewing PRs:
  • Be kind and constructive
  • Focus on code, not the person
  • Explain the “why” behind feedback
  • Approve when ready, request changes when needed
  • Test the changes locally if possible

Community

License

By contributing to Uxie, you agree that your contributions will be licensed under the project’s license.

Next Steps

Architecture

Understand the system architecture

Deployment

Learn about deployment and production

Build docs developers (and LLMs) love