readme
When the user wants to create or update a README.md file for a project. Also use when the user says 'write readme,' 'create readme,' 'document this project,' 'project documentation,' or asks for help with README.md. This skill creates absurdly thorough documentation covering local setup, architecture, and deployment.
README Generator
You are an expert technical writer creating comprehensive project documentation. Your goal is to write a README.md that is absurdly thorough—the kind of documentation you wish every project had.
When to Use This Skill
Use this skill when:
The Three Purposes of a README
Before Writing
Step 1: Deep Codebase Exploration
Before writing a single line of documentation, thoroughly explore the codebase. You MUST understand:
Project Structure
Configuration Files
Database
Key Dependencies
Scripts and Commands
Step 2: Identify Deployment Target
Look for these files to determine deployment platform and tailor instructions:
Dockerfile / docker-compose.yml → Docker-based deploymentvercel.json / .vercel/ → Vercelnetlify.toml → Netlifyfly.toml → Fly.iorailway.json / railway.toml → Railwayrender.yaml → Renderapp.yaml → Google App EngineProcfile → Heroku or Heroku-like platforms.ebextensions/ → AWS Elastic Beanstalkserverless.yml → Serverless Frameworkterraform/ / *.tf → Terraform/Infrastructure as Codek8s/ / kubernetes/ → KubernetesIf no deployment config exists, provide general guidance with Docker as the recommended approach.
Step 3: Ask Only If Critical
Only ask the user questions if you cannot determine:
Otherwise, proceed with exploration and writing.
README Structure
Write the README with these sections in order:
1. Project Title and Overview
# Project NameBrief description of what the project does and who it's for. 2-3 sentences max.
Key Features
Feature 1
Feature 2
Feature 3 2. Tech Stack
List all major technologies:
## Tech StackLanguage: Ruby 3.3+
Framework: Rails 7.2+
Frontend: Inertia.js with React
Database: PostgreSQL 16
Background Jobs: Solid Queue
Caching: Solid Cache
Styling: Tailwind CSS
Deployment: [Detected platform] 3. Prerequisites
What must be installed before starting:
## PrerequisitesNode.js 20 or higher
PostgreSQL 15 or higher (or Docker)
pnpm (recommended) or npm
A Google Cloud project for OAuth (optional for development) 4. Getting Started
The complete local development guide:
## Getting Started\1. Clone the Repository
\
\\bash\
git clone https://github.com/user/repo.git
cd repo
\\2. Install Ruby Dependencies
Ensure you have Ruby 3.3+ installed (via rbenv, asdf, or mise):
\
\\bash\
bundle install
\\3. Install JavaScript Dependencies
\
\\bash\
yarn install
\\4. Environment Setup
Copy the example environment file:
\
\\bash\
cp .env.example .env
\\Configure the following variables:
<div class="overflow-x-auto my-6"><table class="min-w-full divide-y divide-border border border-border"><thead><tr><th class="px-4 py-2 text-left text-sm font-semibold text-foreground bg-muted/50">Variable</th><th class="px-4 py-2 text-left text-sm font-semibold text-foreground bg-muted/50">Description</th><th class="px-4 py-2 text-left text-sm font-semibold text-foreground bg-muted/50">Example</th></tr></thead><tbody class="divide-y divide-border"><tr><td class="px-4 py-2 text-sm text-foreground"><code class="bg-muted px-1 py-0.5 rounded text-xs break-words">DATABASE_URL</code></td><td class="px-4 py-2 text-sm text-foreground">PostgreSQL connection string</td><td class="px-4 py-2 text-sm text-foreground"><code class="bg-muted px-1 py-0.5 rounded text-xs break-words">postgresql://localhost/myapp_development</code></td></tr><tr><td class="px-4 py-2 text-sm text-foreground"><code class="bg-muted px-1 py-0.5 rounded text-xs break-words">REDIS_URL</code></td><td class="px-4 py-2 text-sm text-foreground">Redis connection (if used)</td><td class="px-4 py-2 text-sm text-foreground"><code class="bg-muted px-1 py-0.5 rounded text-xs break-words">redis://localhost:6379/0</code></td></tr><tr><td class="px-4 py-2 text-sm text-foreground"><code class="bg-muted px-1 py-0.5 rounded text-xs break-words">SECRET_KEY_BASE</code></td><td class="px-4 py-2 text-sm text-foreground">Rails secret key</td><td class="px-4 py-2 text-sm text-foreground"><code class="bg-muted px-1 py-0.5 rounded text-xs break-words">bin/rails secret</code></td></tr><tr><td class="px-4 py-2 text-sm text-foreground"><code class="bg-muted px-1 py-0.5 rounded text-xs break-words">RAILS_MASTER_KEY</code></td><td class="px-4 py-2 text-sm text-foreground">For credentials encryption</td><td class="px-4 py-2 text-sm text-foreground">Check <code class="bg-muted px-1 py-0.5 rounded text-xs break-words">config/master.key</code></td></tr></tbody></table></div>
5. Database Setup
Start PostgreSQL (if using Docker):
\
\\bash\
docker run --name postgres -e POSTGRES_PASSWORD=postgres -p 5432:5432 -d postgres:16
\\Create and set up the database:
\
\\bash\
bin/rails db:setup
\\This runs
db:create,db:schema:load, anddb:seed.For existing databases, run migrations:
\
\\bash\
bin/rails db:migrate
\\6. Start Development Server
Using Foreman/Overmind (recommended, runs Rails + Vite):
\
\\bash\
bin/dev
\\Or manually:
\
\\bashTerminal 1: Rails server
bin/rails server
Terminal 2: Vite dev server (for Inertia/React)
bin/vite dev
\\Open http://localhost:3000 in your browser.
Include every step. Assume the reader is setting up on a fresh machine.
5. Architecture Overview
This is where you go absurdly deep:
## Architecture\Directory Structure
\
\\\
├── app/
│ ├── controllers/ # Rails controllers
│ │ ├── concerns/ # Shared controller modules
│ │ └── api/ # API-specific controllers
│ ├── models/ # ActiveRecord models
│ │ └── concerns/ # Shared model modules
│ ├── jobs/ # Background jobs (Solid Queue)
│ ├── mailers/ # Email templates
│ ├── views/ # Rails views (minimal with Inertia)
│ └── frontend/ # Inertia.js React components
│ ├── components/ # Reusable UI components
│ ├── layouts/ # Page layouts
│ ├── pages/ # Inertia page components
│ └── lib/ # Frontend utilities
├── config/
│ ├── routes.rb # Route definitions
│ ├── database.yml # Database configuration
│ └── initializers/ # App initializers
├── db/
│ ├── migrate/ # Database migrations
│ ├── schema.rb # Current schema
│ └── seeds.rb # Seed data
├── lib/
│ └── tasks/ # Custom Rake tasks
└── public/ # Static assets
\\Request Lifecycle
Request hits Rails router ( config/routes.rb)Middleware stack processes request (authentication, sessions, etc.) Controller action executes Models interact with PostgreSQL via ActiveRecord Inertia renders React component with props Response sent to browser Data Flow
\
\\\
User Action → React Component → Inertia Visit → Rails Controller → ActiveRecord → PostgreSQL
↓
React Props ← Inertia Response ←
\\Key Components
Authentication
Devise/Rodauth for user authentication Session-based auth with encrypted cookies authenticate_user!before_action for protected routesInertia.js Integration (
app/frontend/)React components receive props from Rails controllers inertia_renderin controllers passes data to frontendShared data via inertia_sharefor layout propsBackground Jobs (
app/jobs/)Solid Queue for job processing Jobs stored in PostgreSQL (no Redis required) Dashboard at /jobsfor monitoringDatabase (
app/models/)ActiveRecord models with associations Query objects for complex queries Concerns for shared model behavior Database Schema
\
\\
users
├── id (bigint, PK)
├── email (string, unique, not null)
├── encrypted_password (string)
├── name (string)
├── created_at (datetime)
└── updated_at (datetime)posts
├── id (bigint, PK)
├── title (string, not null)
├── content (text)
├── published (boolean, default: false)
├── user_id (bigint, FK → users)
├── created_at (datetime)
└── updated_at (datetime)solid_queue_jobs (background jobs)
├── id (bigint, PK)
├── queue_name (string)
├── class_name (string)
├── arguments (json)
├── scheduled_at (datetime)
└── ...
\\
6. Environment Variables
Complete reference for all env vars:
## Environment Variables\Required
<div class="overflow-x-auto my-6"><table class="min-w-full divide-y divide-border border border-border"><thead><tr><th class="px-4 py-2 text-left text-sm font-semibold text-foreground bg-muted/50">Variable</th><th class="px-4 py-2 text-left text-sm font-semibold text-foreground bg-muted/50">Description</th><th class="px-4 py-2 text-left text-sm font-semibold text-foreground bg-muted/50">How to Get</th></tr></thead><tbody class="divide-y divide-border"><tr><td class="px-4 py-2 text-sm text-foreground"><code class="bg-muted px-1 py-0.5 rounded text-xs break-words">DATABASE_URL</code></td><td class="px-4 py-2 text-sm text-foreground">PostgreSQL connection string</td><td class="px-4 py-2 text-sm text-foreground">Your database provider</td></tr><tr><td class="px-4 py-2 text-sm text-foreground"><code class="bg-muted px-1 py-0.5 rounded text-xs break-words">SECRET_KEY_BASE</code></td><td class="px-4 py-2 text-sm text-foreground">Rails secret for sessions/cookies</td><td class="px-4 py-2 text-sm text-foreground">Run <code class="bg-muted px-1 py-0.5 rounded text-xs break-words">bin/rails secret</code></td></tr><tr><td class="px-4 py-2 text-sm text-foreground"><code class="bg-muted px-1 py-0.5 rounded text-xs break-words">RAILS_MASTER_KEY</code></td><td class="px-4 py-2 text-sm text-foreground">Decrypts credentials file</td><td class="px-4 py-2 text-sm text-foreground">Check <code class="bg-muted px-1 py-0.5 rounded text-xs break-words">config/master.key</code> (not in git)</td></tr></tbody></table></div>
Optional
<div class="overflow-x-auto my-6"><table class="min-w-full divide-y divide-border border border-border"><thead><tr><th class="px-4 py-2 text-left text-sm font-semibold text-foreground bg-muted/50">Variable</th><th class="px-4 py-2 text-left text-sm font-semibold text-foreground bg-muted/50">Description</th><th class="px-4 py-2 text-left text-sm font-semibold text-foreground bg-muted/50">Default</th></tr></thead><tbody class="divide-y divide-border"><tr><td class="px-4 py-2 text-sm text-foreground"><code class="bg-muted px-1 py-0.5 rounded text-xs break-words">REDIS_URL</code></td><td class="px-4 py-2 text-sm text-foreground">Redis connection string (for caching/ActionCable)</td><td class="px-4 py-2 text-sm text-foreground">-</td></tr><tr><td class="px-4 py-2 text-sm text-foreground"><code class="bg-muted px-1 py-0.5 rounded text-xs break-words">RAILS_LOG_LEVEL</code></td><td class="px-4 py-2 text-sm text-foreground">Logging verbosity</td><td class="px-4 py-2 text-sm text-foreground"><code class="bg-muted px-1 py-0.5 rounded text-xs break-words">debug</code> (dev), <code class="bg-muted px-1 py-0.5 rounded text-xs break-words">info</code> (prod)</td></tr><tr><td class="px-4 py-2 text-sm text-foreground"><code class="bg-muted px-1 py-0.5 rounded text-xs break-words">RAILS_MAX_THREADS</code></td><td class="px-4 py-2 text-sm text-foreground">Puma thread count</td><td class="px-4 py-2 text-sm text-foreground"><code class="bg-muted px-1 py-0.5 rounded text-xs break-words">5</code></td></tr><tr><td class="px-4 py-2 text-sm text-foreground"><code class="bg-muted px-1 py-0.5 rounded text-xs break-words">WEB_CONCURRENCY</code></td><td class="px-4 py-2 text-sm text-foreground">Puma worker count</td><td class="px-4 py-2 text-sm text-foreground"><code class="bg-muted px-1 py-0.5 rounded text-xs break-words">2</code></td></tr><tr><td class="px-4 py-2 text-sm text-foreground"><code class="bg-muted px-1 py-0.5 rounded text-xs break-words">SMTP_ADDRESS</code></td><td class="px-4 py-2 text-sm text-foreground">Mail server hostname</td><td class="px-4 py-2 text-sm text-foreground">-</td></tr><tr><td class="px-4 py-2 text-sm text-foreground"><code class="bg-muted px-1 py-0.5 rounded text-xs break-words">SMTP_PORT</code></td><td class="px-4 py-2 text-sm text-foreground">Mail server port</td><td class="px-4 py-2 text-sm text-foreground"><code class="bg-muted px-1 py-0.5 rounded text-xs break-words">587</code></td></tr></tbody></table></div>
Rails Credentials
Sensitive values should be stored in Rails encrypted credentials:
\
\\bashEdit credentials (opens in $EDITOR)
bin/rails credentials:edit
Or for environment-specific credentials
RAILS_ENV=production bin/rails credentials:edit
\\Credentials file structure:
\\\yaml\
secret_key_base: xxx
stripe:
public_key: pk_xxx
secret_key: sk_xxx
google:
client_id: xxx
client_secret: xxx
\\Access in code:
Rails.application.credentials.stripe[:secret_key]Environment-Specific
Development
\\\\
DATABASE_URL=postgresql://localhost/myapp_development
REDIS_URL=redis://localhost:6379/0
\\Production
\\\\
DATABASE_URL=<production-connection-string>
RAILS_ENV=production
RAILS_SERVE_STATIC_FILES=true
\\
7. Available Scripts
## Available Scripts<div class="overflow-x-auto my-6"><table class="min-w-full divide-y divide-border border border-border"><thead><tr><th class="px-4 py-2 text-left text-sm font-semibold text-foreground bg-muted/50">Command</th><th class="px-4 py-2 text-left text-sm font-semibold text-foreground bg-muted/50">Description</th></tr></thead><tbody class="divide-y divide-border"><tr><td class="px-4 py-2 text-sm text-foreground"><code class="bg-muted px-1 py-0.5 rounded text-xs break-words">bin/dev</code></td><td class="px-4 py-2 text-sm text-foreground">Start development server (Rails + Vite via Foreman)</td></tr><tr><td class="px-4 py-2 text-sm text-foreground"><code class="bg-muted px-1 py-0.5 rounded text-xs break-words">bin/rails server</code></td><td class="px-4 py-2 text-sm text-foreground">Start Rails server only</td></tr><tr><td class="px-4 py-2 text-sm text-foreground"><code class="bg-muted px-1 py-0.5 rounded text-xs break-words">bin/vite dev</code></td><td class="px-4 py-2 text-sm text-foreground">Start Vite dev server only</td></tr><tr><td class="px-4 py-2 text-sm text-foreground"><code class="bg-muted px-1 py-0.5 rounded text-xs break-words">bin/rails console</code></td><td class="px-4 py-2 text-sm text-foreground">Open Rails console (IRB with app loaded)</td></tr><tr><td class="px-4 py-2 text-sm text-foreground"><code class="bg-muted px-1 py-0.5 rounded text-xs break-words">bin/rails db:migrate</code></td><td class="px-4 py-2 text-sm text-foreground">Run pending database migrations</td></tr><tr><td class="px-4 py-2 text-sm text-foreground"><code class="bg-muted px-1 py-0.5 rounded text-xs break-words">bin/rails db:rollback</code></td><td class="px-4 py-2 text-sm text-foreground">Rollback last migration</td></tr><tr><td class="px-4 py-2 text-sm text-foreground"><code class="bg-muted px-1 py-0.5 rounded text-xs break-words">bin/rails db:seed</code></td><td class="px-4 py-2 text-sm text-foreground">Run database seeds</td></tr><tr><td class="px-4 py-2 text-sm text-foreground"><code class="bg-muted px-1 py-0.5 rounded text-xs break-words">bin/rails db:reset</code></td><td class="px-4 py-2 text-sm text-foreground">Drop, create, migrate, and seed database</td></tr><tr><td class="px-4 py-2 text-sm text-foreground"><code class="bg-muted px-1 py-0.5 rounded text-xs break-words">bin/rails routes</code></td><td class="px-4 py-2 text-sm text-foreground">List all routes</td></tr><tr><td class="px-4 py-2 text-sm text-foreground"><code class="bg-muted px-1 py-0.5 rounded text-xs break-words">bin/rails test</code></td><td class="px-4 py-2 text-sm text-foreground">Run test suite (Minitest)</td></tr><tr><td class="px-4 py-2 text-sm text-foreground"><code class="bg-muted px-1 py-0.5 rounded text-xs break-words">bundle exec rspec</code></td><td class="px-4 py-2 text-sm text-foreground">Run test suite (RSpec, if used)</td></tr><tr><td class="px-4 py-2 text-sm text-foreground"><code class="bg-muted px-1 py-0.5 rounded text-xs break-words">bin/rails assets:precompile</code></td><td class="px-4 py-2 text-sm text-foreground">Compile assets for production</td></tr><tr><td class="px-4 py-2 text-sm text-foreground"><code class="bg-muted px-1 py-0.5 rounded text-xs break-words">bin/rubocop</code></td><td class="px-4 py-2 text-sm text-foreground">Run Ruby linter</td></tr><tr><td class="px-4 py-2 text-sm text-foreground"><code class="bg-muted px-1 py-0.5 rounded text-xs break-words">yarn lint</code></td><td class="px-4 py-2 text-sm text-foreground">Run JavaScript/TypeScript linter</td></tr></tbody></table></div>
8. Testing
## Testing\Running Tests
\
\\bashRun all tests (Minitest)
bin/rails test
Run all tests (RSpec, if used)
bundle exec rspec
Run specific test file
bin/rails test test/models/user_test.rb
bundle exec rspec spec/models/user_spec.rbRun tests matching a pattern
bin/rails test -n /creates_user/
bundle exec rspec -e "creates user"Run system tests (browser tests)
bin/rails test:system
Run with coverage (SimpleCov)
COVERAGE=true bin/rails test
\\Test Structure
\
\\
test/ # Minitest structure
├── controllers/ # Controller tests
├── models/ # Model unit tests
├── integration/ # Integration tests
├── system/ # System/browser tests
├── fixtures/ # Test data
└── test_helper.rb # Test configurationspec/ # RSpec structure (if used)
├── models/
├── requests/
├── system/
├── factories/ # FactoryBot factories
├── support/
└── rails_helper.rb
\\\Writing Tests
Minitest example:
\\\ruby
require "test_helper"class UserTest < ActiveSupport::TestCase
test "creates user with valid attributes" do
user = User.new(email: "test@example.com", name: "Test User")
assert user.valid?
endtest "requires email" do
user = User.new(name: "Test User")
assert_not user.valid?
assert_includes user.errors[:email], "can't be blank"
end
end
\\\RSpec example:
\\\ruby
require "rails_helper"RSpec.describe User, type: :model do
describe "validations" do
it "is valid with valid attributes" do
user = build(:user)
expect(user).to be_valid
endit "requires an email" do
user = build(:user, email: nil)
expect(user).not_to be_valid
expect(user.errors[:email]).to include("can't be blank")
endend
end
\\\Frontend Testing
For Inertia/React components:
\
\\bash\
yarn test
\\\
\\typescript
import { render, screen } from '@testing-library/react'
import { Dashboard } from './Dashboard'describe('Dashboard', () => {
it('renders user name', () => {
render(<Dashboard user={{ name: 'Josh' }} />)
expect(screen.getByText('Josh')).toBeInTheDocument()
})
})
\\\
9. Deployment
Tailor this to detected platform (look for Dockerfile, fly.toml, render.yaml, kamal/, etc.):
## Deployment\Kamal (Recommended for Rails)
If using Kamal for deployment:
\
\\bashSetup Kamal (first time)
kamal setup
Deploy
kamal deploy
Rollback to previous version
kamal rollback
View logs
kamal app logs
Run console on production
kamal app exec --interactive 'bin/rails console'
\\Configuration lives in
config/deploy.yml.Docker
Build and run:
\
\\bashBuild image
docker build -t myapp .
Run with environment variables
docker run -p 3000:3000 \
-e DATABASE_URL=postgresql://... \
-e SECRET_KEY_BASE=... \
-e RAILS_ENV=production \
myapp
\\\Heroku
\
\\bashCreate app
heroku create myapp
Add PostgreSQL
heroku addons:create heroku-postgresql:mini
Set environment variables
heroku config:set SECRET_KEY_BASE=$(bin/rails secret)
heroku config:set RAILS_MASTER_KEY=$(cat config/master.key)Deploy
git push heroku main
Run migrations
heroku run bin/rails db:migrate
\\\Fly.io
\
\\bashLaunch (first time)
fly launch
Deploy
fly deploy
Run migrations
fly ssh console -C "bin/rails db:migrate"
Open console
fly ssh console -C "bin/rails console"
\\\Render
If
render.yamlexists, connect your repo to Render and it will auto-deploy.Manual setup:
bundle install && bin/rails assets:precompilebin/rails serverManual/VPS Deployment
\\\bash
On the server:
Pull latest code
git pull origin main
Install dependencies
bundle install --deployment
Compile assets
RAILS_ENV=production bin/rails assets:precompile
Run migrations
RAILS_ENV=production bin/rails db:migrate
Restart application server (e.g., Puma via systemd)
sudo systemctl restart myapp
\\\
10. Troubleshooting
## Troubleshooting\Database Connection Issues
Error:
could not connect to server: Connection refusedSolution:
Verify PostgreSQL is running: pg_isreadyordocker psCheck DATABASE_URLformat:postgresql://USER:PASSWORD@HOST:PORT/DATABASEEnsure database exists: bin/rails db:createPending Migrations
Error:
Migrations are pendingSolution:
\\\bash\
bin/rails db:migrate
\\Asset Compilation Issues
Error:
The asset "application.css" is not present in the asset pipelineSolution:
\\\bashClear and recompile assets
bin/rails assets:clobber
bin/rails assets:precompile
\\Bundle Install Failures
Error: Native extension build failures
Solution:
\
\\bash # macOS
brew install postgresql libpq
# Ubuntu
sudo apt-get install libpq-dev
\
\\bundle installCredentials Issues
Error: ActiveSupport::MessageEncryptor::InvalidMessage
Solution:
The master key doesn't match the credentials file. Either:
config/master.key from another team memberrm config/credentials.yml.enc && bin/rails credentials:editVite/Inertia Issues
Error: Vite Ruby - Build failed
Solution:
\\\bash
Clear Vite cache
rm -rf node_modules/.vite
Reinstall JS dependencies
rm -rf node_modules && yarn install
\\\
Solid Queue Issues
Error: Jobs not processing
Solution:
Ensure the queue worker is running:
\\\bash
bin/jobs
or
bin/rails solid_queue:start
\\\
11. Contributing (Optional)
Include if open source or team project.
12. License (Optional)
Writing Principles
pnpm if the project uses it, npm if it uses npm, etc.Output Format
Generate a complete README.md file with:
bash, typescript, etc.)Write the README directly to README.md in the project root.