A customizable ranked list web application built with React, TypeScript, and Tailwind CSS. Create "Top 10" style lists for comics, albums, films, games, or anything else you want to rank and share.
Demo: Jenny & Jacob's Top 10 Comic Series
- Responsive accordion-style layout with smooth animations
- Configurable branding, theming, and content
- Image galleries with lightbox viewer
- Attribution system for credits (writers, artists, etc.)
- Free hosting via GitHub Pages
- No backend required—just static files
- Bun
- A GitHub account (for free hosting)
- Visit github.com/jekrch/tops
- Click the Fork button in the top-right corner
- Select your account as the destination
- (Optional) Rename the repository to match your list theme (e.g.,
my-top-albums)
git clone https://github.com/YOUR_USERNAME/YOUR_REPO_NAME.git
cd YOUR_REPO_NAMEbun installbun run devOpen http://localhost:5173 to see your list.
All configuration lives in two files inside src/data/:
This file contains two exports:
export const listConfig: ListConfig = {
branding: {
authorName: "Your Name's", // Shown above the title
authorInitials: "YN", // Badge display (2 characters)
authorLink: "https://your.site" // Optional link
},
meta: {
title: "Top {n} {subject}", // {n} and {subject} are interpolated
listSize: 10, // Number of items
subject: "Albums", // What you're ranking
subtitle: "My Favorites of {year}",
year: 2025
},
content: {
introText: "A paragraph introducing your list...",
expandPrompt: "tap to expand" // Hint text when nothing is expanded
},
theme: {
accentColor: "jk-teal" // Tailwind color class (see Theming below)
}
};export const rankItems: RankItem[] = [
{
rank: 1,
name: "Item Name",
category: "Publisher / Label / Studio", // Optional
attributions: [
{ label: "Director", values: ["Jane Doe"], showOnCard: true },
{ label: "Writer", values: ["John Smith"] }
],
cover_image: "/images/items/item-cover.jpg",
sample_images: [
"/images/items/item-sample-1.jpg",
"/images/items/item-sample-2.jpg"
],
description: "Publisher or official description of the item.",
description_source: { // Optional attribution
name: "Official Site",
link: "https://example.com"
},
review_comment: "Your personal take on why this item made the list.",
link: "https://example.com/item"
},
// ... more items
];See src/types/RankTypes.ts and src/types/ListConfig.ts for the complete type definitions.
Images go in the public/images/ directory:
public/
└── images/
└── items/
├── item-name-cover.jpg
├── item-name-1.jpg
└── item-name-2.jpg
Reference them in your config with paths starting from /images/:
cover_image: "/images/items/item-name-cover.jpg"The default accent color is jk-teal. To use a different color:
- Define your color in your Tailwind config or CSS:
/* In src/index.css or your global styles */
@theme {
--color-my-accent: #your-hex-color;
}- Update
listConfig.theme.accentColor:
theme: {
accentColor: "my-accent"
}Standard Tailwind colors like blue-500, emerald-400, etc. also work if configured.
Your fork includes a GitHub Action that automatically builds and deploys your site.
-
In your forked repository, go to Settings → Pages
-
Under "Build and deployment", set:
- Source: GitHub Actions
-
Update
vite.config.tswith your repository name:
export default defineConfig({
base: '/YOUR_REPO_NAME/',
// ...
})- Commit and push your changes:
git add .
git commit -m "Configure for deployment"
git push-
The GitHub Action will automatically build and deploy your site
-
Your site will be available at
https://YOUR_USERNAME.github.io/YOUR_REPO_NAME/
To use a custom domain like mytopten.com:
- Go to Settings → Pages
- Enter your domain under "Custom domain"
- Update your DNS settings as prompted
- Set
base: '/'invite.config.ts
| Command | Description |
|---|---|
bun run dev |
Start development server |
bun run build |
Build for production |
bun run preview |
Preview production build locally |
bun run deploy |
Build and deploy to GitHub Pages |
bun run lint |
Run ESLint |
- React
- TypeScript
- Vite
- Tailwind 4
- Lucide React (icons)
MIT — use this however you like.