[{"data":1,"prerenderedAt":803},["ShallowReactive",2],{"blog-list":3,"blog-post-\u002Fblog\u002Fmy-second-article":525},[4,417],{"id":5,"title":6,"body":7,"date":409,"description":410,"extension":411,"meta":412,"navigation":227,"path":413,"seo":414,"stem":415,"__hash__":416},"blog\u002Fblog\u002Fmy-second-article.md","My Second Article",{"type":8,"value":9,"toc":403},"minimark",[10,15,19,24,27,145,152,156,159,251,269,273,283,389,392,396,399],[11,12,14],"h1",{"id":13},"building-a-design-system-with-typescript","Building a Design System with TypeScript",[16,17,18],"p",{},"Design systems are the backbone of scalable frontend development. When paired with TypeScript, they become even more powerful — giving you autocomplete, type safety, and self-documenting APIs across every component.",[20,21,23],"h2",{"id":22},"why-typescript-in-a-design-system","Why TypeScript in a Design System?",[16,25,26],{},"A design system without types is a design system that relies on documentation nobody reads. TypeScript turns your component API into the documentation.",[28,29,34],"pre",{"className":30,"code":31,"language":32,"meta":33,"style":33},"language-ts shiki shiki-themes github-light github-dark","interface ButtonProps {\n  variant: 'primary' | 'secondary' | 'ghost';\n  size: 'sm' | 'md' | 'lg';\n  disabled?: boolean;\n  onClick?: () => void;\n}\n","ts","",[35,36,37,54,82,105,120,139],"code",{"__ignoreMap":33},[38,39,42,46,50],"span",{"class":40,"line":41},"line",1,[38,43,45],{"class":44},"szBVR","interface",[38,47,49],{"class":48},"sScJk"," ButtonProps",[38,51,53],{"class":52},"sVt8B"," {\n",[38,55,57,61,64,68,71,74,76,79],{"class":40,"line":56},2,[38,58,60],{"class":59},"s4XuR","  variant",[38,62,63],{"class":44},":",[38,65,67],{"class":66},"sZZnC"," 'primary'",[38,69,70],{"class":44}," |",[38,72,73],{"class":66}," 'secondary'",[38,75,70],{"class":44},[38,77,78],{"class":66}," 'ghost'",[38,80,81],{"class":52},";\n",[38,83,85,88,90,93,95,98,100,103],{"class":40,"line":84},3,[38,86,87],{"class":59},"  size",[38,89,63],{"class":44},[38,91,92],{"class":66}," 'sm'",[38,94,70],{"class":44},[38,96,97],{"class":66}," 'md'",[38,99,70],{"class":44},[38,101,102],{"class":66}," 'lg'",[38,104,81],{"class":52},[38,106,108,111,114,118],{"class":40,"line":107},4,[38,109,110],{"class":59},"  disabled",[38,112,113],{"class":44},"?:",[38,115,117],{"class":116},"sj4cs"," boolean",[38,119,81],{"class":52},[38,121,123,126,128,131,134,137],{"class":40,"line":122},5,[38,124,125],{"class":48},"  onClick",[38,127,113],{"class":44},[38,129,130],{"class":52}," () ",[38,132,133],{"class":44},"=>",[38,135,136],{"class":116}," void",[38,138,81],{"class":52},[38,140,142],{"class":40,"line":141},6,[38,143,144],{"class":52},"}\n",[16,146,147,148,151],{},"With this interface, consumers can't accidentally pass ",[35,149,150],{},"variant=\"danger\""," if it doesn't exist — the compiler catches it first.",[20,153,155],{"id":154},"tokens-as-constants","Tokens as Constants",[16,157,158],{},"Design tokens — colors, spacing, typography — should live as typed constants rather than raw strings scattered through stylesheets.",[28,160,162],{"className":30,"code":161,"language":32,"meta":33,"style":33},"export const colors = {\n  amber: '#C9A84C',\n  void: '#080808',\n  inkMuted: 'rgba(240, 237, 230, 0.55)',\n} as const;\n\nexport type Color = keyof typeof colors;\n",[35,163,164,180,191,201,211,223,229],{"__ignoreMap":33},[38,165,166,169,172,175,178],{"class":40,"line":41},[38,167,168],{"class":44},"export",[38,170,171],{"class":44}," const",[38,173,174],{"class":116}," colors",[38,176,177],{"class":44}," =",[38,179,53],{"class":52},[38,181,182,185,188],{"class":40,"line":56},[38,183,184],{"class":52},"  amber: ",[38,186,187],{"class":66},"'#C9A84C'",[38,189,190],{"class":52},",\n",[38,192,193,196,199],{"class":40,"line":84},[38,194,195],{"class":52},"  void: ",[38,197,198],{"class":66},"'#080808'",[38,200,190],{"class":52},[38,202,203,206,209],{"class":40,"line":107},[38,204,205],{"class":52},"  inkMuted: ",[38,207,208],{"class":66},"'rgba(240, 237, 230, 0.55)'",[38,210,190],{"class":52},[38,212,213,216,219,221],{"class":40,"line":122},[38,214,215],{"class":52},"} ",[38,217,218],{"class":44},"as",[38,220,171],{"class":44},[38,222,81],{"class":52},[38,224,225],{"class":40,"line":141},[38,226,228],{"emptyLinePlaceholder":227},true,"\n",[38,230,232,234,237,240,242,245,248],{"class":40,"line":231},7,[38,233,168],{"class":44},[38,235,236],{"class":44}," type",[38,238,239],{"class":48}," Color",[38,241,177],{"class":44},[38,243,244],{"class":44}," keyof",[38,246,247],{"class":44}," typeof",[38,249,250],{"class":52}," colors;\n",[16,252,253,254,257,258,261,262,264,265,268],{},"The ",[35,255,256],{},"as const"," assertion narrows the type to exact string literals, so ",[35,259,260],{},"colors.amber"," is typed as ",[35,263,187],{},", not just ",[35,266,267],{},"string",".",[20,270,272],{"id":271},"component-variants-with-cva","Component Variants with CVA",[16,274,275,282],{},[276,277,281],"a",{"href":278,"rel":279},"https:\u002F\u002Fcva.style",[280],"nofollow","Class Variance Authority (CVA)"," is a lightweight library that pairs well with this approach. It lets you define component variants declaratively:",[28,284,286],{"className":30,"code":285,"language":32,"meta":33,"style":33},"const button = cva('btn-base', {\n  variants: {\n    variant: {\n      primary: 'btn-primary',\n      ghost: 'btn-ghost',\n    },\n    size: {\n      sm: 'btn-sm',\n      md: 'btn-md',\n    },\n  },\n});\n",[35,287,288,310,315,320,330,340,345,350,361,372,377,383],{"__ignoreMap":33},[38,289,290,293,296,298,301,304,307],{"class":40,"line":41},[38,291,292],{"class":44},"const",[38,294,295],{"class":116}," button",[38,297,177],{"class":44},[38,299,300],{"class":48}," cva",[38,302,303],{"class":52},"(",[38,305,306],{"class":66},"'btn-base'",[38,308,309],{"class":52},", {\n",[38,311,312],{"class":40,"line":56},[38,313,314],{"class":52},"  variants: {\n",[38,316,317],{"class":40,"line":84},[38,318,319],{"class":52},"    variant: {\n",[38,321,322,325,328],{"class":40,"line":107},[38,323,324],{"class":52},"      primary: ",[38,326,327],{"class":66},"'btn-primary'",[38,329,190],{"class":52},[38,331,332,335,338],{"class":40,"line":122},[38,333,334],{"class":52},"      ghost: ",[38,336,337],{"class":66},"'btn-ghost'",[38,339,190],{"class":52},[38,341,342],{"class":40,"line":141},[38,343,344],{"class":52},"    },\n",[38,346,347],{"class":40,"line":231},[38,348,349],{"class":52},"    size: {\n",[38,351,353,356,359],{"class":40,"line":352},8,[38,354,355],{"class":52},"      sm: ",[38,357,358],{"class":66},"'btn-sm'",[38,360,190],{"class":52},[38,362,364,367,370],{"class":40,"line":363},9,[38,365,366],{"class":52},"      md: ",[38,368,369],{"class":66},"'btn-md'",[38,371,190],{"class":52},[38,373,375],{"class":40,"line":374},10,[38,376,344],{"class":52},[38,378,380],{"class":40,"line":379},11,[38,381,382],{"class":52},"  },\n",[38,384,386],{"class":40,"line":385},12,[38,387,388],{"class":52},"});\n",[16,390,391],{},"The returned function is fully typed — the variant keys are inferred directly from the config.",[20,393,395],{"id":394},"closing-thoughts","Closing Thoughts",[16,397,398],{},"A well-typed design system pays dividends every time a new developer joins your team or you revisit code six months later. The upfront investment in types and tokens is small compared to the long-term reduction in bugs and inconsistency.",[400,401,402],"style",{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":33,"searchDepth":56,"depth":56,"links":404},[405,406,407,408],{"id":22,"depth":56,"text":23},{"id":154,"depth":56,"text":155},{"id":271,"depth":56,"text":272},{"id":394,"depth":56,"text":395},"2026-04-12","Thoughts on building design systems with TypeScript","md",{},"\u002Fblog\u002Fmy-second-article",{"title":6,"description":410},"blog\u002Fmy-second-article","vbOoZ8w2ob28oj1Et6u68uLDg4S497aouq9ehtaRr4w",{"id":418,"title":419,"body":420,"date":518,"description":519,"extension":411,"meta":520,"navigation":227,"path":521,"seo":522,"stem":523,"__hash__":524},"blog\u002Fblog\u002Fmy-first-article.md","My First Article",{"type":8,"value":421,"toc":509},[422,425,428,432,435,440,451,455,458,462,465,469,472,476,479,483,486,490,506],[11,423,419],{"id":424},"my-first-article",[16,426,427],{},"Hello world, this is my first post.",[11,429,431],{"id":430},"nuxt-vs-nextjs-key-differences","Nuxt vs Next.js: Key Differences",[16,433,434],{},"Both Nuxt and Next.js are popular frameworks for building web applications, but they serve different ecosystems and have distinct philosophies.",[436,437,439],"h3",{"id":438},"framework-foundation","Framework Foundation",[16,441,442,446,447,450],{},[443,444,445],"strong",{},"Next.js"," is built on React, while ",[443,448,449],{},"Nuxt"," is built on Vue. This is the fundamental difference that influences everything else about these frameworks.",[436,452,454],{"id":453},"developer-experience","Developer Experience",[16,456,457],{},"Nuxt is known for its opinionated folder structure and conventions that reduce boilerplate code. Next.js offers more flexibility but requires more explicit configuration. Nuxt's file-based routing and automatic component registration can speed up development, while Next.js requires manual imports and route definitions.",[436,459,461],{"id":460},"performance","Performance",[16,463,464],{},"Both frameworks support static site generation and server-side rendering. Next.js has a larger ecosystem and more third-party resources, while Nuxt excels at providing an integrated experience out of the box.",[436,466,468],{"id":467},"ecosystem","Ecosystem",[16,470,471],{},"React developers will find Next.js more comfortable due to the vast React ecosystem. Vue developers benefit from Nuxt's tight integration with Vue's tooling and libraries.",[436,473,475],{"id":474},"state-management","State Management",[16,477,478],{},"Next.js is typically used with Redux, Zustand, or other React state libraries. Nuxt integrates seamlessly with Pinia (or Vuex) for Vue-based state management.",[436,480,482],{"id":481},"learning-curve","Learning Curve",[16,484,485],{},"If you're already familiar with React, Next.js has a gentler learning curve. If you know Vue, Nuxt will feel more natural.",[436,487,489],{"id":488},"when-to-choose-what","When to Choose What",[491,492,493,500],"ul",{},[494,495,496,499],"li",{},[443,497,498],{},"Choose Nuxt"," if you prefer Vue, want an opinionated structure, and value developer productivity",[494,501,502,505],{},[443,503,504],{},"Choose Next.js"," if you're in the React ecosystem, need maximum flexibility, or require extensive community resources",[16,507,508],{},"Both are excellent choices—it ultimately depends on your team's expertise and project requirements.",{"title":33,"searchDepth":56,"depth":56,"links":510},[511,512,513,514,515,516,517],{"id":438,"depth":84,"text":439},{"id":453,"depth":84,"text":454},{"id":460,"depth":84,"text":461},{"id":467,"depth":84,"text":468},{"id":474,"depth":84,"text":475},{"id":481,"depth":84,"text":482},{"id":488,"depth":84,"text":489},"2026-04-11","This is my first blog post",{},"\u002Fblog\u002Fmy-first-article",{"title":419,"description":519},"blog\u002Fmy-first-article","PSuoT8irgjYM4kwIlBE6aE1MBHXxVoMbn8vxcBQ7MTk",{"id":5,"title":6,"body":526,"date":409,"description":410,"extension":411,"meta":801,"navigation":227,"path":413,"seo":802,"stem":415,"__hash__":416},{"type":8,"value":527,"toc":795},[528,530,532,534,536,612,616,618,620,690,700,702,707,787,789,791,793],[11,529,14],{"id":13},[16,531,18],{},[20,533,23],{"id":22},[16,535,26],{},[28,537,538],{"className":30,"code":31,"language":32,"meta":33,"style":33},[35,539,540,548,566,584,594,608],{"__ignoreMap":33},[38,541,542,544,546],{"class":40,"line":41},[38,543,45],{"class":44},[38,545,49],{"class":48},[38,547,53],{"class":52},[38,549,550,552,554,556,558,560,562,564],{"class":40,"line":56},[38,551,60],{"class":59},[38,553,63],{"class":44},[38,555,67],{"class":66},[38,557,70],{"class":44},[38,559,73],{"class":66},[38,561,70],{"class":44},[38,563,78],{"class":66},[38,565,81],{"class":52},[38,567,568,570,572,574,576,578,580,582],{"class":40,"line":84},[38,569,87],{"class":59},[38,571,63],{"class":44},[38,573,92],{"class":66},[38,575,70],{"class":44},[38,577,97],{"class":66},[38,579,70],{"class":44},[38,581,102],{"class":66},[38,583,81],{"class":52},[38,585,586,588,590,592],{"class":40,"line":107},[38,587,110],{"class":59},[38,589,113],{"class":44},[38,591,117],{"class":116},[38,593,81],{"class":52},[38,595,596,598,600,602,604,606],{"class":40,"line":122},[38,597,125],{"class":48},[38,599,113],{"class":44},[38,601,130],{"class":52},[38,603,133],{"class":44},[38,605,136],{"class":116},[38,607,81],{"class":52},[38,609,610],{"class":40,"line":141},[38,611,144],{"class":52},[16,613,147,614,151],{},[35,615,150],{},[20,617,155],{"id":154},[16,619,158],{},[28,621,622],{"className":30,"code":161,"language":32,"meta":33,"style":33},[35,623,624,636,644,652,660,670,674],{"__ignoreMap":33},[38,625,626,628,630,632,634],{"class":40,"line":41},[38,627,168],{"class":44},[38,629,171],{"class":44},[38,631,174],{"class":116},[38,633,177],{"class":44},[38,635,53],{"class":52},[38,637,638,640,642],{"class":40,"line":56},[38,639,184],{"class":52},[38,641,187],{"class":66},[38,643,190],{"class":52},[38,645,646,648,650],{"class":40,"line":84},[38,647,195],{"class":52},[38,649,198],{"class":66},[38,651,190],{"class":52},[38,653,654,656,658],{"class":40,"line":107},[38,655,205],{"class":52},[38,657,208],{"class":66},[38,659,190],{"class":52},[38,661,662,664,666,668],{"class":40,"line":122},[38,663,215],{"class":52},[38,665,218],{"class":44},[38,667,171],{"class":44},[38,669,81],{"class":52},[38,671,672],{"class":40,"line":141},[38,673,228],{"emptyLinePlaceholder":227},[38,675,676,678,680,682,684,686,688],{"class":40,"line":231},[38,677,168],{"class":44},[38,679,236],{"class":44},[38,681,239],{"class":48},[38,683,177],{"class":44},[38,685,244],{"class":44},[38,687,247],{"class":44},[38,689,250],{"class":52},[16,691,253,692,257,694,261,696,264,698,268],{},[35,693,256],{},[35,695,260],{},[35,697,187],{},[35,699,267],{},[20,701,272],{"id":271},[16,703,704,282],{},[276,705,281],{"href":278,"rel":706},[280],[28,708,709],{"className":30,"code":285,"language":32,"meta":33,"style":33},[35,710,711,727,731,735,743,751,755,759,767,775,779,783],{"__ignoreMap":33},[38,712,713,715,717,719,721,723,725],{"class":40,"line":41},[38,714,292],{"class":44},[38,716,295],{"class":116},[38,718,177],{"class":44},[38,720,300],{"class":48},[38,722,303],{"class":52},[38,724,306],{"class":66},[38,726,309],{"class":52},[38,728,729],{"class":40,"line":56},[38,730,314],{"class":52},[38,732,733],{"class":40,"line":84},[38,734,319],{"class":52},[38,736,737,739,741],{"class":40,"line":107},[38,738,324],{"class":52},[38,740,327],{"class":66},[38,742,190],{"class":52},[38,744,745,747,749],{"class":40,"line":122},[38,746,334],{"class":52},[38,748,337],{"class":66},[38,750,190],{"class":52},[38,752,753],{"class":40,"line":141},[38,754,344],{"class":52},[38,756,757],{"class":40,"line":231},[38,758,349],{"class":52},[38,760,761,763,765],{"class":40,"line":352},[38,762,355],{"class":52},[38,764,358],{"class":66},[38,766,190],{"class":52},[38,768,769,771,773],{"class":40,"line":363},[38,770,366],{"class":52},[38,772,369],{"class":66},[38,774,190],{"class":52},[38,776,777],{"class":40,"line":374},[38,778,344],{"class":52},[38,780,781],{"class":40,"line":379},[38,782,382],{"class":52},[38,784,785],{"class":40,"line":385},[38,786,388],{"class":52},[16,788,391],{},[20,790,395],{"id":394},[16,792,398],{},[400,794,402],{},{"title":33,"searchDepth":56,"depth":56,"links":796},[797,798,799,800],{"id":22,"depth":56,"text":23},{"id":154,"depth":56,"text":155},{"id":271,"depth":56,"text":272},{"id":394,"depth":56,"text":395},{},{"title":6,"description":410},1776200878990]