Rulesets
Guide your AI to follow your team's coding standards, best practices, and project-specific conventions. Rulesets ensure consistent, high-quality code generation across your entire project.
Written By Nick Gatzoulis
Last updated 4 months ago
What are rulesets?
Rulesets are Markdown files that instruct the AI how to write code for your project. They live in your GitHub repository and guide every code generation decision.

Why use rulesets:
Enforce standards: Define naming conventions, code style, and architecture patterns
Integrate tools: Add guidelines for Supabase, Stripe, or other services you use
Save time: The AI follows your rules automatically—no need to repeat instructions
Maintain quality: Prevent common mistakes by documenting what to avoid
Onboard faster: New team members see your conventions in action
How it works: When you send a prompt, App2's AI agents read your rulesets before writing code. This ensures every generated file matches your team's standards.
Understanding ruleset types
App2 provides two types of rulesets that work together.
Default rulesets
App2 creates these automatically when your project starts. They provide baseline code quality guidelines.
Included defaults:
shared-guidelines.md- Universal best practices for all projectsweb-guidelines.mdormobile-guidelines.md- Template-specific standardsIntegration rules under
integrations/<service>/- Guidelines for Supabase, Stripe, etc.
Key points:
Generated based on your project template (web or mobile)
Located at
rules/default/in your repositoryYou can edit defaults to match your preferences
Cannot be deleted (but you can override them)
Auto-restored if missing during sandbox sync
Custom rulesets
Create your own rules to enforce team-specific conventions.
Use cases:
Company coding standards
API design patterns
Error handling requirements
Testing strategies
Documentation requirements
Security policies
Key points:
Located at
rules/custom/in your repositoryOrganize in folders for better structure
Fully editable and deletable
Work alongside defaults
Committed directly to your GitHub repo
Accessing rulesets
Find the rulesets manager in your project settings.
How to open:
Open your project in App2
Click Settings in the top navigation
Select Rulesets from the settings menu
View all your project's rulesets in the tree view
What you'll see:
Left panel: Tree view of Default and Custom folders
Right panel: Markdown editor with Write/Preview tabs
Actions: New Rule, Update Rule, Delete (custom only)
Note: Rulesets are only editable when your project status is READY or FAILED.
Managing rulesets

Viewing a ruleset
Steps:
Open Settings → Rulesets
Expand Default or Custom folders in the tree
Click a ruleset file to view its content
Switch between Write and Preview tabs
The Preview tab renders your Markdown so you can verify formatting.
Creating a custom ruleset
Steps:
Click New Rule button (top right)
Choose Custom rules location (default rules are read-only)
Enter an optional folder path:
Leave empty to save in root:
rules/custom/Use subfolders:
backend,frontend/components, etc.
Enter filename (automatically adds
.mdextension)Review the resulting path preview
Click Continue
Write your ruleset content in Markdown
Click Create Rule
Example paths:
rules/custom/api-conventions.md- Root levelrules/custom/backend/error-handling.md- Organized by arearules/custom/frontend/components/button-patterns.md- Deeply nested
Naming tips:
Use descriptive names:
authentication-standards.md, notrules1.mdUse kebab-case for filenames:
code-review-checklist.mdGroup related rules in folders:
backend/,frontend/,integrations/
Tip: Create a
rules/custom/team-conventions.mdfile as your starting point for team standards.
Editing a ruleset
Steps:
Select the ruleset from the tree view
Modify content in the Write tab
Preview changes in the Preview tab
Click Update Rule when finished
Changes commit automatically to GitHub
For default rulesets: You can update defaults to match your preferences. Your changes are preserved even when the sandbox restarts.
For custom rulesets: Edit freely. Changes sync immediately to your repository.
Deleting a custom ruleset
Steps:
Select the custom ruleset in the tree
Click Delete button
Confirm deletion
File is removed from your repository
Warning: Only custom rulesets can be deleted. Default rulesets cannot be removed.
Best practices
Write effective rulesets that guide the AI without being overly restrictive.
Structure your rules
Use clear sections:
# API Design Standards
## Naming conventions
- Use camelCase for variable names
- Use PascalCase for component names
- Use SCREAMING_SNAKE_CASE for constants
## Error handling
- Always wrap async functions in try-catch blocks
- Return typed errors, never throw strings
- Log errors with context using logger.error()
## Response format
All API endpoints must return:
{
"success": boolean,
"data": T | null,
"error": { "code": string, "message": string } | null
}
Keep it scannable:
Use headings (H2, H3) for major sections
Use bullet points for lists of rules
Include code examples for clarity
Add inline code formatting with backticks
Be specific and actionable
Good examples:
"Use
async/awaitinstead of.then()chains for all asynchronous operations""Import UI components from
@/components/uiusing named imports""Prefix all database query functions with
db(e.g.,dbGetUser,dbCreatePost)"
Avoid vague rules:
"Write good code" (too vague)
"Don't make mistakes" (not actionable)
"Follow best practices" (unclear what practices)
Include examples
Show the AI exactly what you want:
## Button components
Use the Button component from our design system:
```tsx
import { Button } from '@/components/ui/button';
// Good
<Button variant="primary" size="md" onClick={handleClick}>
Save Changes
</Button>
// Avoid
<button className="custom-button" onClick={handleClick}>
Save Changes
</button>
### Explain the why
Help the AI understand the reasoning behind rules:
```markdown
## State management
Use Zustand for global state instead of Context API.
Why: Zustand provides better performance with selective subscriptions and simpler syntax. Context re-renders all consumers on any state change.
Example:
// store/useAuthStore.ts
import { create } from 'zustand';
export const useAuthStore = create((set) => ({
user: null,
setUser: (user) => set({ user }),
}));
Organize by concern
Create focused rulesets:
authentication.md- Auth patterns, session handlingdatabase.md- Query patterns, migrations, indexestesting.md- Test structure, naming, coveragestyling.md- CSS conventions, theme usage
This keeps rules discoverable and maintainable.
Examples
# Team Coding Standards
## TypeScript rules
- Enable strict mode in tsconfig.json
- Never use `any` type—always define proper types
- Export types alongside implementation
- Use named exports over default exports
## Import order
Organize imports in this order:
1. React and framework imports
2. Third-party libraries
3. Local components
4. Local utilities
5. Type imports
6. CSS imports
## Function naming
- Event handlers: `handleClick`, `handleSubmit`
- Data fetchers: `fetchUsers`, `loadProfile`
- Boolean checks: `isLoading`, `hasError`, `canEdit`
- Transformers: `formatDate`, `parseResponse`
## Error boundaries
Wrap all route components with ErrorBoundary:
```tsx
<ErrorBoundary fallback={<ErrorPage />}>
<YourComponent />
</ErrorBoundary>
### Example 2: Supabase integration rules
```markdown
# Supabase Best Practices
## Database queries
- Use Row Level Security (RLS) for all tables
- Create policies for `SELECT`, `INSERT`, `UPDATE`, `DELETE`
- Test queries with different user roles
## Client initialization
Initialize once and reuse:
```typescript
import { createClient } from '@supabase/supabase-js';
export const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
);