Skip to content
Live demo

Frontend (React + Tailwind)

SparkFeed’s frontend is a modern React application built for speed and developer experience.

React 18 + TypeScript
TanStack Router (file-based, type-safe routing)
TanStack Query (server state management)
Zustand (client-side state)
Tailwind CSS (utility-first styling)

SparkFeed uses React 18 with:

  • Concurrent Features: Better rendering prioritization for large lists
  • useTransition: Marks article list updates as non-urgent for smoother navigation
  • Strict Mode: Enabled in development to surface issues early
  • TypeScript: All components are fully typed

TanStack Router is a type-safe, file-based router for React.

  • Type-safe navigation: TypeScript knows every route and its params
  • Search params as state: URL search params are typed and validated
  • Nested layouts: Sidebar and main content are separate layout routes
  • Loaders: Data is fetched before a route renders, not after
src/client/routes/
├── __root.tsx # Root layout (header, sidebar)
├── index.tsx # Home / All articles
├── feed/
│ └── $feedId.tsx # Single feed view
├── folder/
│ └── $folderId.tsx # Folder view
├── favorites.tsx # Saved articles
└── article/
└── $articleId.tsx # Article reader

SparkFeed uses Tailwind CSS for all styling.

// tailwind.config.ts
export default {
content: ['./src/client/**/*.{tsx,ts}'],
darkMode: 'class',
theme: {
extend: {
colors: {
accent: {
DEFAULT: '#6366f1',
light: '#818cf8',
dark: '#4f46e5',
},
},
fontFamily: {
sans: ['Inter', 'system-ui', 'sans-serif'],
mono: ['JetBrains Mono', 'monospace'],
},
},
},
};
// ArticleCard.tsx
export function ArticleCard({ article }: { article: Article }) {
return (
<article className="group flex flex-col gap-1 px-4 py-3 hover:bg-slate-800/50
transition-colors cursor-pointer border-b border-slate-800">
<h3 className="text-sm font-medium text-slate-100
group-hover:text-indigo-400 transition-colors line-clamp-2">
{article.title}
</h3>
<p className="text-xs text-slate-400 line-clamp-2">
{article.summary}
</p>
<div className="flex items-center gap-2 mt-1 text-xs text-slate-500">
<span>{article.feedTitle}</span>
<span>·</span>
<time>{formatRelativeDate(article.publishedAt)}</time>
</div>
</article>
);
}
PackageVersionPurpose
react18.xUI framework
@tanstack/react-router1.xType-safe routing
@tanstack/react-query5.xServer state management
zustand4.xClient state
tailwindcss3.xUtility-first CSS
typescript5.xType safety