[{"data":1,"prerenderedAt":143},["ShallowReactive",2],{"post-source-published-packages-en":3,"related-posts-source-published-packages-en":107,"related-categories-source-published-packages-en":131},{"id":4,"title":5,"author":6,"authorImageUrl":7,"authorUrl":8,"body":9,"categorySlug":83,"categoryText":84,"dateModified":85,"datePublished":85,"description":86,"extension":87,"faqs":88,"image":95,"language":96,"meta":97,"navigation":98,"path":99,"seo":100,"stem":101,"tags":102,"__hash__":106},"blog\u002Fblog\u002Fsource-published-packages.md","Shipping a Vue Library Without a Build Step","Bruma","\u002Fimages\u002Fauthors\u002Fbruma.jpg","https:\u002F\u002Fbrumaombra.com",{"type":10,"value":11,"toc":74},"minimark",[12,17,26,37,41,44,51,54,60,65,68,71],[13,14,16],"h2",{"id":15},"most-libraries-ship-a-second-copy-of-themselves","Most libraries ship a second copy of themselves",[18,19,20,21,25],"p",{},"A typical component library has two versions of its code: the source you edit and a compiled bundle in ",[22,23,24],"code",{},"dist\u002F"," that you publish. Keeping them in sync is a job of its own, with a bundler config, declaration files, and the occasional bug that only exists in the build.",[18,27,28,29,32,33,36],{},"UI Vintage skips the second copy. The npm package contains the ",[22,30,31],{},".vue"," and ",[22,34,35],{},".ts"," files as they are written, and the Nuxt module tells each app to compile them like its own code.",[13,38,40],{"id":39},"what-you-get-for-free","What you get for free",[18,42,43],{},"The obvious win is less tooling. The less obvious one is that the library behaves exactly like app code, because it is compiled by the same tools with the same settings.",[45,46],"flow",{":items":47,"description":48,"orientation":49,"title":50},"[\"npm install\",\"Module registers\",\"App compiles source\",\"Tree-shaken page\"]","The library never builds itself. The app does it once, together with everything else.","horizontal","From install to page",[18,52,53],{},"Tailwind scans the library's templates directly, so every utility class a component uses ends up in the app's stylesheet. Vite tree-shakes per subpath import, so a page that only uses a button never loads the date picker.",[55,56],"code-block",{"code":57,"language":58,"title":59},"npm install @brumaombra\u002Fui-vintage\nnpx nuxi module add @brumaombra\u002Fui-vintage\n","bash","Installing the library",[61,62,64],"h3",{"id":63},"the-tradeoffs-are-real","The tradeoffs are real",[18,66,67],{},"The strongest argument against this approach is that it ties the library to its framework. A compiled bundle could, in theory, run in any Vue app. A source package needs the toolchain it was written for, which here means Nuxt.",[18,69,70],{},"There is also a version contract to keep. Because apps compile the source, a library update can surface a type error in the app's build that a prebuilt bundle would have hidden. That is arguably a feature, but it does mean releases need a typecheck before they ship.",[18,72,73],{},"For a library whose only consumers are Nuxt apps, the trade is easy to accept. The point is not that build steps are bad. It is that a build step is code too, and the cheapest code to maintain is the code you don't need.",{"title":75,"searchDepth":76,"depth":76,"links":77},"",2,[78,79],{"id":15,"depth":76,"text":16},{"id":39,"depth":76,"text":40,"children":80},[81],{"id":63,"depth":82,"text":64},3,"engineering","Engineering","2026-08-12T00:00:00Z","UI Vintage publishes its source and lets each Nuxt app compile it. That choice removes a whole class of problems, and adds a couple of new ones.","md",[89,92],{"question":90,"answer":91},"Does publishing source make apps slower to build?","A little, because the app compiles the library along with its own code. In practice the difference is small, and the app only compiles the components it actually imports.",{"question":93,"answer":94},"Can a non-Nuxt Vue app use the package?","Not directly. The components rely on Nuxt features such as NuxtImg and the module that injects styles and translations.","\u002Fimages\u002Fblog\u002Fsource-published-packages\u002Fcover.jpg","en",{},true,"\u002Fblog\u002Fsource-published-packages",{"title":5,"description":86},"blog\u002Fsource-published-packages",[103,104,105],"Nuxt","Component Libraries","Tooling","jh3jv8Fk_RFP36Ep2Os9mUFmmE37nV7M6mspcjoflvY",[108,114,120,126],{"title":109,"description":110,"image":111,"categoryText":112,"path":113},"Shipping the Blog Migration Into the Library","A practical summary of what changed once the original blog implementation was moved into a reusable Nuxt-friendly component library.","\u002Fimages\u002Fblog\u002Fshipping-the-blog-migration\u002Fcover.jpg","Product Updates","\u002Fblog\u002Fshipping-the-blog-migration",{"title":115,"description":116,"image":117,"categoryText":118,"path":119},"Designing a Reusable Editorial System","How we turned a one-off blog UI into a reusable content surface that still feels intentional once it leaves the original product.","\u002Fimages\u002Fblog\u002Fdesigning-a-reusable-editorial-system\u002Fcover.jpg","Design Systems","\u002Fblog\u002Fdesigning-a-reusable-editorial-system",{"title":121,"description":122,"image":123,"categoryText":124,"path":125},"Why Spring Animations Feel Faster Than They Are","A spring that overshoots slightly can take longer than a plain fade and still feel quicker. Here is why, and where the trick stops working.","\u002Fimages\u002Fblog\u002Fwhy-spring-animations-feel-faster\u002Fcover.jpg","Motion Design","\u002Fblog\u002Fwhy-spring-animations-feel-faster",{"title":127,"description":128,"image":129,"categoryText":118,"path":130},"Dark Mode Is a Second Design, Not a Filter","Inverting colors gives you a dark theme that technically works and looks slightly wrong everywhere. Semantic tokens fix most of it. Shadows and accents need extra care.","\u002Fimages\u002Fblog\u002Fdark-mode-is-a-second-design\u002Fcover.jpg","\u002Fblog\u002Fdark-mode-is-a-second-design",[132,134,137,141],{"name":118,"slug":133,"count":76,"image":129},"design-systems",{"name":112,"slug":135,"count":136,"image":111},"product-updates",1,{"name":138,"slug":139,"count":136,"image":140},"Accessibility","accessibility","\u002Fimages\u002Fblog\u002Ffocus-states-people-notice\u002Fcover.jpg",{"name":124,"slug":142,"count":136,"image":123},"motion-design",1792259222304]