A static React application for comparing items side-by-side across shared attributes. Whether you're evaluating databases, programming languages, libraries, or any other category, Lineup helps you make informed decisions by presenting data in a clear, comparable format.
- Side-by-side comparisons - View multiple candidates simultaneously with their attributes aligned
- Multiple comparison types - Support for databases, languages, libraries, frameworks, and more
- Rich value types - Display data as text, numbers, ratings, tags, icons, file sizes, durations, and more
- Collapsible attribute groups - Organize related attributes into logical sections
- Value ranking - Visual indicators for best/worst values based on configurable direction (higher or lower is better)
- Source citations - Every data point can include sources and comments, shown in tooltips on hover
- Responsive design - Works on desktop and mobile devices
# Clone the repository
git clone https://github.com/your-username/lineup.git
cd lineup
# Install dependencies
cd app
pnpm install
# Start development server
pnpm devThe application will be available at http://localhost:5173.
cd app
pnpm buildThe built files will be in app/dist/ and can be served by any static file server.
lineup/
├── app/ # React application
│ ├── src/
│ │ ├── components/ # React components
│ │ ├── lib/ # Utilities
│ │ └── types/ # TypeScript types
│ └── package.json
├── data/ # Comparison data
│ ├── index.json # List of available comparisons
│ └── <comparison-type>/ # One directory per comparison type
│ ├── index.json # List of candidates
│ ├── attributes.json # Attribute definitions
│ └── <candidate>.json # Candidate data files
└── docs/ # Documentation
Lineup ships with Claude Code skills under .claude/skills/ that handle each step of creating and maintaining comparison data. The skills are invoked as slash commands inside Claude Code.
| Skill | Purpose |
|---|---|
/new-type <type> [seed] |
Draft data/<type>/RESEARCH.md for a brand-new comparison type through a short Socratic scoping conversation (purpose, scope, attribute groups, initial candidates). Writes only the research guide so you can iterate on it before any schema files are generated. |
/scaffold-type <type> [candidate-id …] |
Translate RESEARCH.md into data/<type>/attributes.json, register the type in the top-level data/index.json, and scaffold empty-values stubs for each Initial Candidate into data/<type>/index.json. Re-run later (with or without explicit ids) to scaffold additional candidates. |
/add-candidate <type> <name> [url / description / reason] |
Add a single candidate after a scope-fit check against RESEARCH.md's Scope section. Creates the stub, appends to index.json, and appends a - [ ] <Name> — <reason> (added <date>) line to RESEARCH.md's Initial Candidates list. |
/discover-candidates <type> [hint] |
Search the web for candidates that fit the type's scope, filter and deduplicate against the existing roster, present the picks for selection, and scaffold the chosen ones the same way /add-candidate does. |
/extend-comparison <type> <description> |
Append one or more new attributes (or a whole new attribute group) to an already-scaffolded type. Updates RESEARCH.md's Attribute Groups tables and attributes.json in lockstep. Existing candidates render — for the new attribute until filled in. |
/gather-data <type> [candidate] [attribute-or-group] |
Research and populate attribute values for a candidate via web sources. Records {value, source, comment} per attribute, stamps lastVerified, and ticks the RESEARCH.md checkbox on first research. |
Creating a new comparison type end-to-end:
- Scope the type.
/new-type <type> <optional seed>— iterate on the generatedRESEARCH.mduntil purpose, scope, attribute groups, and initial candidates read well. - Scaffold schema and stubs.
/scaffold-type <type>— generatesattributes.json, registers the type indata/index.json, and creates empty stubs for each Initial Candidate. - Research each candidate.
/gather-data <type>— auto-picks the next under-researched candidate, searches primary sources, and populates thevaluesblock. Repeat until every candidate is covered.
- Add a candidate you have in mind.
/add-candidate <type> <name> <optional url/description/reason>, then/gather-data <type> <candidate-id>to research it. - Discover candidates to consider.
/discover-candidates <type> [hint]surfaces a vetted picklist from the web; picks are scaffolded automatically. - Add a new attribute.
/extend-comparison <type> <description>, then/gather-data <type> <candidate> <new-attribute-id>per existing candidate to fill the column.
The underlying layout is plain JSON and markdown — see Project Structure and the data schema in CLAUDE.md. The skills exist for convenience, not as a gate; direct edits work fine.
Lineup supports various value types for attributes:
| Type | Description | Example |
|---|---|---|
integer |
Whole numbers | Release year, version number |
decimal |
Decimal numbers | Performance score |
filesize |
File sizes (auto-formatted) | Binary size, memory usage |
duration |
Time durations | Build time, response time |
date |
Calendar dates (year, month-year, or full) | Release date, initial release year |
datetime |
Date and time | Last updated, event timestamp |
text |
Free-form text | Description, license |
boolean |
Yes/No values | Feature support flags |
rating |
Star ratings or similar | Community rating |
tags |
Labeled categories | Supported platforms |
icon |
Icons or emojis | Logo, status indicator |
link |
Clickable URLs | Documentation, repository |
{
"name": "PostgreSQL",
"description": "Advanced open-source relational database",
"url": "https://postgresql.org",
"values": {
"license": {
"value": "PostgreSQL License",
"source": ["https://www.postgresql.org/about/licence/"]
},
"acid-compliant": {
"value": true
},
"initial-release": {
"value": 1996
}
}
}- React - UI framework
- Vite - Build tool and dev server
- TypeScript - Type safety
- Tailwind CSS - Styling
- shadcn/ui - UI component library
pnpm dev # Start development server
pnpm build # Build for production
pnpm preview # Preview production build
pnpm lint # Run linter
pnpm format # Format codeContributions are welcome! Whether you want to:
- Add new comparison types with researched data
- Improve the UI/UX
- Fix bugs or add features
- Improve documentation
Please feel free to open an issue or submit a pull request.