Package Exports
- livecv
- livecv/styles.css
- livecv/theme.css
Readme
livecv
Your portfolio answers questions. Define a KB, render a live persona.
livecv turns a typed config + markdown KB into a generative-UI personal site. Visitors type a question, an LLM picks components from a Zod-typed catalog, and the page renders bespoke per query.
Install
npm install livecv @ai-sdk/anthropic @ai-sdk/react ai \
@json-render/core @json-render/react @json-render/shadcn \
motion lucide-react zodThe four files you write
my-portfolio/
├── livecv.config.ts — typed config (identity, career, projects, blog, model)
├── content/kb.md — prose KB (voice, principles, what you're focused on)
├── app/page.tsx — <PersonaSite config={config} />
└── app/api/generate/route.ts — export const POST = createHandler({ config })Minimum example
// livecv.config.ts
import fs from "node:fs";
import path from "node:path";
import { defineConfig } from "livecv";
export default defineConfig({
identity: {
name: "Jane Doe",
role: "Software Engineer",
bio: "...",
email: "jane@example.com",
links: { github: "https://github.com/janedoe" },
},
career: [
{ start: "2024", end: "Present", title: "Senior Engineer", org: "Foo",
detail: "...", tech: ["TypeScript"], status: "current" },
],
projects: [
{ id: "thing", title: "thing", tldr: "...", description: "...",
tech: ["TypeScript"], cluster: "tools",
howItWorks: ["..."], keyInsight: "..." },
],
clusters: [{ id: "tools", label: "Tools" }],
blog: [],
kbContent: fs.readFileSync(path.join(process.cwd(), "content/kb.md"), "utf-8"),
model: "claude-haiku-4-5",
});// app/page.tsx
"use client";
import { PersonaSite } from "livecv";
import config from "@/livecv.config";
export default function Page() {
return <PersonaSite config={config} />;
}// app/api/generate/route.ts
import { createHandler } from "livecv/handler";
import config from "@/livecv.config";
export const POST = createHandler({ config });
export const maxDuration = 60;/* app/globals.css */
@import "tailwindcss";
@import "livecv/styles.css"; /* pre-compiled utility CSS for livecv components */
@import "livecv/theme.css"; /* CSS variable tokens */livecv ships its own pre-compiled Tailwind utility CSS (dist/styles.css, ~44KB) generated by scanning the package's compiled components at build time. That means consumers don't need an @source directive pointing at node_modules — the utilities used by livecv components are guaranteed to be in the final bundle through a normal package import.
# .env.local — in your Next.js app (see .env.local.example in this repo)
ANTHROPIC_API_KEY=sk-ant-...That's it. npm run dev and you have a live persona portfolio.
See .env.local.example for the full list of env vars (just
ANTHROPIC_API_KEYis required; the rest are optional).
What renders
The LLM picks from this catalog per question:
- ProfileBlock — your card with name/role/links
- CareerTimeline — chronological rail with patent + education, supports a
focusprop to dim/highlight rows by topic - ProjectGrid — your projects, filtered by cluster, with "more on GitHub" footer
- ProjectDeepDive — full breakdown of one project
- TechStack — tag cloud sized by frequency
- BlogList / BlogPostCard — your writing
- PrincipleList — your engineering principles (only for philosophy questions, never for experience)
- LeadershipStories — STAR-format experience stories, generated fresh per question
- ProofPoints — tag + claim + evidence rows for hire-style answers
- PersonalNote — one-sentence first-person opener, always freshly generated
- Callout / Text / Link — prose primitives
Project IDs, blog slugs, and cluster IDs become Zod enums automatically — the LLM cannot hallucinate references that don't exist. Bad specs fail validation; the renderer falls back gracefully.
Theme
Override any CSS variable in your own globals.css:
:root {
--lc-foreground: #000;
--lc-background: #fff;
/* ... */
}Dark mode is the .dark class on <html> (or anywhere up the tree).
Status
v0.1 — works for a single user portfolio. Not yet:
- Custom component overrides (slot system)
- Multi-tenant
- Edge runtime
- Rate-limit / abuse protection (use Upstash separately for now)
Reference
The reference implementation is ai.sayantan.sh — its source consumes this package via a file: reference and supplies only its own config + KB.