<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Fred K. Schott</title>
    <description>The latest articles on Forem by Fred K. Schott (@fredkschott).</description>
    <link>https://forem.com/fredkschott</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F204935%2F78770dec-02c1-4ad2-b9ea-6f923b7bc8ad.jpeg</url>
      <title>Forem: Fred K. Schott</title>
      <link>https://forem.com/fredkschott</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/fredkschott"/>
    <language>en</language>
    <item>
      <title>6 More Things I Learned Building Snowpack to 20,000 Stars (Part 2)</title>
      <dc:creator>Fred K. Schott</dc:creator>
      <pubDate>Wed, 15 Sep 2021 22:58:01 +0000</pubDate>
      <link>https://forem.com/fredkschott/5-more-things-i-learned-building-snowpack-to-20-000-stars-5dc9</link>
      <guid>https://forem.com/fredkschott/5-more-things-i-learned-building-snowpack-to-20-000-stars-5dc9</guid>
      <description>&lt;p&gt;This article is the second entry in a two-part series. &lt;a href="https://dev.to/fredkschott/5-things-i-learned-while-building-snowpack-to-20-000-stars-b9d"&gt;In the first post&lt;/a&gt;, I went over the early history of Snowpack and how we grew an open source project to find our first set of users. In this post, I want to focus on what happened next: how do you maintain and continue to grow a large project at this scale?&lt;/p&gt;

&lt;p&gt;This will be an entertaining read for anyone interested in open source software. The highlighted lessons are for current (or aspiring!) open source maintainers of large and/or growing open source projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;If the first post in this series was about everything that I did right with Snowpack, then this post is about everything that went wrong.&lt;/p&gt;

&lt;p&gt;We came into the year with big expectations: Voted &lt;a href="https://osawards.com/javascript/2020" rel="noopener noreferrer"&gt;"Productivity Booster of the Year"&lt;/a&gt; in the OS Awards. Voted #1 &amp;amp; #2 placement in the &lt;a href="https://2020.stateofjs.com/en-US/technologies/build-tools/" rel="noopener noreferrer"&gt;"2020 State of JavaScript"&lt;/a&gt; survey on build tools. Exploding from 200,000 downloads in 2020 to 1.3M in 2021.&lt;/p&gt;

&lt;p&gt;When you do something like this for the first time, you're never going to get it 100% right. This was my first experience maintaining an open source project of this scale. I had started plenty of new repos in the past, and some of them were even well liked, but none had ever grown this big. We didn't have a roadmap for this transition, and I made plenty of mistakes that I now see in hindsight.&lt;/p&gt;

&lt;p&gt;I want to make it clear that I'm incredibly proud of this project and &lt;a href="https://github.com/snowpackjs/snowpack/graphs/contributors" rel="noopener noreferrer"&gt;the people&lt;/a&gt; who have contributed to it. Snowpack pushed the entire web development industry forward, and that's pretty cool. Even if you never use Snowpack directly, the work that we pioneered -- specifically around npm package handling for ESM and unbundled development --  is being built on and improved on across the entire web tooling landscape in projects like &lt;a href="https://vitejs.dev/" rel="noopener noreferrer"&gt;Vite&lt;/a&gt;, &lt;a href="https://www.skypack.dev/" rel="noopener noreferrer"&gt;Skypack&lt;/a&gt;, &lt;a href="https://jspm.org/" rel="noopener noreferrer"&gt;JSPM CDN&lt;/a&gt; and others.&lt;/p&gt;

&lt;p&gt;This post is my attempt to create a guide for anyone who finds themselves in a similar position one day.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson 1: Dogfood large, real-world projects
&lt;/h2&gt;

&lt;p&gt;Real-world testing is &lt;em&gt;super&lt;/em&gt; important. I'm sure that sounds cliche, but its true. We had a few starter projects that we could test Snowpack against, but they were all small and simple. This created a huge experience gap between our internal projects and our actual users.&lt;/p&gt;

&lt;p&gt;People tend to think of &lt;a href="https://en.wikipedia.org/wiki/Eating_your_own_dog_food" rel="noopener noreferrer"&gt;"dogfooding"&lt;/a&gt; as a way to prevent bugs, but I've found it to be most useful as a way to align with your users. It's impossible to make good decisions about something that you don't know well. Without some kind of real-world dogfooding, you often end up prioritizing the wrong features and fixes.&lt;/p&gt;

&lt;p&gt;This is unfortunately one thing that large-scale corporate open source does well. Facebook is able to test a new React feature or bugfix across a codebase of &lt;a href="https://github.com/facebook/react/issues/9463#issuecomment-295643228" rel="noopener noreferrer"&gt;30,000+ components.&lt;/a&gt; They can try things out internally, at scale, before sharing publicly.&lt;/p&gt;

&lt;p&gt;If your project isn't owned by a tech giant, you still have options. If you work somewhere full-time, try to dogfood things within your company. Rich Harris often talks about how &lt;a href="https://twitter.com/rich_harris/status/1329257941510320130" rel="noopener noreferrer"&gt;using Svelte at The New York Times&lt;/a&gt; benefits the framework. Your company could be a real-world playground for new features, API changes, and even &lt;a href="https://twitter.com/Rich_Harris/status/1354491322720268290" rel="noopener noreferrer"&gt;entire pre-release projects.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Snowpack never had a company playground. Yet, we still could have been better about talking to our users and getting feedback before working on features. In retrospect I would have sought out invites to real-world codebases in exchange for some testing and support.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; Dogfood large projects to prevent bugs and useless feature work.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson 2: Painless developer experience is essential
&lt;/h2&gt;

&lt;p&gt;In the early days of a project, you'll be forgiven for a few bugs and odd behaviors. As your project matures, this patience tends to run out. The real problem doesn't have to be a single big bug, but the sum of multiple "poor" user experiences.&lt;/p&gt;

&lt;p&gt;For example, you should &lt;strong&gt;always&lt;/strong&gt; have a clear error message when something breaks. Yes, even if you think that it was the user's fault:  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fblxbd1imgyvmaph98gpq.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fblxbd1imgyvmaph98gpq.gif" alt="a funny gif of a person failing to do a simple task like drinking water from a cup"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;As our audience transitioned from early-adopters to a larger "mainstream" audience, users became less likely to track down odd errors (&lt;code&gt;undefined is not a function&lt;/code&gt; 😱). Instead, they would abandon the project for more familiar/stable alternatives.&lt;/p&gt;

&lt;p&gt;This is also relevant to how you choose new features. "Bundling should be optional" was a core idea baked into Snowpack from the start. If you remember back to &lt;a href="https://dev.to/fredkschott/5-things-i-learned-while-building-snowpack-to-20-000-stars-b9d"&gt;the first post&lt;/a&gt; in this series, that was the idea that our first users fell in love with. As we grew, mainstream users didn't love it so much. They were mostly confused why they had to implement such a simple feature themselves.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; As your audience grows, understand how your users change. Invest in testing, clear error messages, and overall stability. Make sure that the default user experience is good before investing in advanced features.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson 3: Your users won't tell you everything
&lt;/h2&gt;

&lt;p&gt;Snowpack almost powered &lt;a href="https://kit.svelte.dev/" rel="noopener noreferrer"&gt;SvelteKit.&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Rich Harris &lt;a href="https://svelte.dev/blog/whats-the-deal-with-sveltekit" rel="noopener noreferrer"&gt;announced it&lt;/a&gt; at the Svelte Summit conference, and published a blog about how excited he was about our project. We were ecstatic. But right before SvelteKit's public release, they switched out Snowpack for an alternative tool called &lt;a href="http://vitejs.dev/" rel="noopener noreferrer"&gt;Vite&lt;/a&gt;. We found out tool late. The decision had already been made. Their team was unhappy with Snowpack, and we hadn't even noticed!&lt;/p&gt;

&lt;p&gt;You tend to have a strong connection to your users on smaller projects. But as the audience grows, you lose touch a bit. I had gotten so used to this feedback cycle that I hadn't even thought to check in. I had missed the rough edges that the Svelte team was encountering every day, and only got their feedback after it was too late to change any minds.&lt;/p&gt;

&lt;p&gt;It's important for open source leaders to invest in feedback channels. We learned this too late.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; Don't wait for your users to tell you what's wrong. Be proactive about gathering feedback and fixing issues.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson 4: Be consistent
&lt;/h2&gt;

&lt;p&gt;The best part of open source development is the community. As your project grows, you'll see more people stopping by to chat, comment on issues, and maybe even contribute some code. Repeat contributors can become life-long friends.&lt;/p&gt;

&lt;p&gt;Consistency is the best way to build trust in your community. Bursts of productivity are fine for personal projects, but the long stretches of quiet that usually follow are poison to a growing community. This might be the most common mistake that I see large open source projects make. When you step away from your project, contributors and potential future contributors notice. There's nothing worse than putting time into a PR and then having it sit around, uncommented and unnoticed for weeks or months.&lt;/p&gt;

&lt;p&gt;I want to stress that the solution here is &lt;em&gt;not&lt;/em&gt; "just spend more time." That's a guaranteed path to burnout. Instead, spend your time better. It's better to spend an hour or two every week than it is to spend a full day, once a month.&lt;/p&gt;

&lt;p&gt;For what it's worth, this is something that I'm still working on myself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; Be consistent. Don't leave your contributors hanging on code reviews and pull requests.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson 5: Be present and use Discord (seriously.)
&lt;/h2&gt;

&lt;p&gt;I mentioned it before but it's important enough to say again: Use &lt;a href="https://discord.com/" rel="noopener noreferrer"&gt;Discord&lt;/a&gt;. Create a community server as soon as your get your first users. If you already have a Slack community, start thinking about moving. Seriously, it's that much better.&lt;/p&gt;

&lt;p&gt;A new Discord server will only ever be as active as you are. If you never visit it, don't expect much to happen. If people never get a response, don't expect them to stay for long. Calling back to the previous two sections: Consistent presence is the best way to build a community and get valuable feedback from your users.&lt;/p&gt;

&lt;p&gt;Discord also is great at encouraging experimentation. Is someone recommending a great bot (aka integration) for your server? Try it out! Ask them to help integrate, customize, or even teach you how Discord works. If your codebase is daunting, Discord can be a great middle-ground where you can collaborate with (and even learn from) your community.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; Use Discord. Be present + consistent. Embrace the fun side of the platform (emotes/emojis, bots, stickers, etc).  &lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson 6: You can't do it all on your own
&lt;/h2&gt;

&lt;p&gt;It's important to realize when your project has grown beyond your ability to maintain it alone. At that point you'll have a decision: bring on more people, or burn out. &lt;/p&gt;

&lt;p&gt;"It will just be faster if I do it myself" might be true short-term thinking, but its dangerous over the long-term.&lt;/p&gt;

&lt;p&gt;Despite accepting plenty of contributions over the years, I still fell into this trap with Snowpack. A part of me wanted to run the project all by myself, and refused to encouraged larger contributions. I shipped some great stuff during that period, but I also rushed my work. Code quality suffered. I skipped code reviews because I felt I didn't have time for it. And then when I did step away to recover, I would stay away for longer periods and the project would go quiet.&lt;/p&gt;

&lt;p&gt;Ever been so burnt out that you didn't have the energy to realize it? Yeah. It's tough.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; You can't do it all yourself. Building a community can be the most fun part of open source, &lt;em&gt;if you invest in it.&lt;/em&gt; Read up on good open source governance to learn how others do it.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Epilogue: What's Next for Snowpack?
&lt;/h2&gt;

&lt;p&gt;If you're currently an open source maintainer or contributor, I hope that you have found this honest guide useful! This last year has been a wild journey, but I wouldn't trade a moment of it.&lt;/p&gt;

&lt;p&gt;Painful mistakes tend to stick. I've already started to apply these lessons to our newest project, &lt;a href="https://astro.build/" rel="noopener noreferrer"&gt;Astro.&lt;/a&gt; We've already invested in an &lt;a href="https://astro.build/chat" rel="noopener noreferrer"&gt;active Discord,&lt;/a&gt; a healthy &lt;a href="https://github.com/snowpackjs/astro/blob/main/GOVERNANCE.md" rel="noopener noreferrer"&gt;governance model,&lt;/a&gt; a solid test suite, a focus on stability, and a community of amazing maintainers.&lt;/p&gt;

&lt;p&gt;It's a great feeling to step away and know that your project is in good hands.&lt;/p&gt;

&lt;p&gt;To be honest, I'm not sure where Snowpack goes from here. I burnt out on it at the end of last year, and haven't found the energy to return. Usage and downloads began to trend down and the community has gotten quieter. &lt;/p&gt;

&lt;p&gt;At the same time, &lt;a href="https://vitejs.dev/" rel="noopener noreferrer"&gt;Vite&lt;/a&gt; (that Snowpack alternative that now powers SvelteKit) is taking off. To their credit, they do a lot of things really well. The good news is that two tools are very similar and easy to switch out. Even Astro is experimenting with moving from Snowpack to Vite in a future release.&lt;/p&gt;

&lt;p&gt;So maybe it makes sense to wind things down. We asked our community if anyone wanted to get involved in long-term maintenance. But new contributor onboarding takes time that we just can't seem to find any on our end. It's a bit of a Catch-22.&lt;/p&gt;

&lt;p&gt;One other idea would be going back to basics, and bring this story full-circle. The ESM package installer that our first users fell in love with still exists as &lt;a href="https://www.npmjs.com/package/esinstall" rel="noopener noreferrer"&gt;its own package&lt;/a&gt;. The audience for a utility like that would be smaller. It might even be fun!&lt;/p&gt;

&lt;p&gt;Whatever happens, I know that we'll keep learning and keep improving.&lt;/p&gt;

&lt;p&gt;Thanks for reading! &lt;a href="https://twitter.com/FredKSchott/" rel="noopener noreferrer"&gt;Follow me on Twitter&lt;/a&gt; for more updates. If you missed it, check out &lt;a href="https://dev.to/fredkschott/5-things-i-learned-while-building-snowpack-to-20-000-stars-b9d"&gt;the first post&lt;/a&gt; in the series.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>opensource</category>
      <category>snowpack</category>
    </item>
    <item>
      <title>5 Things I Learned Building Snowpack to 20,000 Stars</title>
      <dc:creator>Fred K. Schott</dc:creator>
      <pubDate>Mon, 13 Sep 2021 17:27:18 +0000</pubDate>
      <link>https://forem.com/fredkschott/5-things-i-learned-while-building-snowpack-to-20-000-stars-b9d</link>
      <guid>https://forem.com/fredkschott/5-things-i-learned-while-building-snowpack-to-20-000-stars-b9d</guid>
      <description>&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; &lt;a href="https://dev.to/fredkschott/5-more-things-i-learned-building-snowpack-to-20-000-stars-5dc9"&gt;Part two has been posted!&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My name is &lt;a href="https://twitter.com/FredKSchott"&gt;Fred,&lt;/a&gt; and I created &lt;a href="//snowpack.dev"&gt;Snowpack.&lt;/a&gt; If you're not familiar, Snowpack is a web build tool that fundamentally unlocked the &lt;a href="https://www.youtube.com/watch?v=aee93s9TZVc"&gt;"unbundled web development"&lt;/a&gt; movement that Snowpack, Vite, SvelteKit and other modern dev tools leverage today.&lt;/p&gt;

&lt;p&gt;In this post, I want to share 5 things that I learned growing Snowpack from the initial commit to almost 20,000 GitHub stars and over 1,000,000+ downloads. &lt;/p&gt;

&lt;p&gt;This post is meant for anyone interested in Open Source software. The highlighted lessons are directed at anyone who is interested in starting their own open source project or contributing to an existing project.&lt;/p&gt;

&lt;p&gt;This will be a 2-part series: In this first post I focus on lessons learned creating Snowpack from scratch and finding our first set of users. In &lt;a href="https://dev.to/fredkschott/5-more-things-i-learned-building-snowpack-to-20-000-stars-5dc9"&gt;part two&lt;/a&gt;, I will focus what it's like to maintain a popular open source project, at scale.&lt;/p&gt;

&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;A couple of years ago, I started an experimental JavaScript project. Codename: &lt;a href="https://www.pika.dev/"&gt;Pika.&lt;/a&gt; It had a cute, blue mouse mascot and a fun vibe that a bunch of smaller experimental projects could live under. Its unifying mission could be best summarized as, &lt;a href="https://www.pika.dev/about"&gt;"ESM is this cool new technology, lets do more stuff with it."&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That first year of Pika may have been the most productive year of my life. I created @pika/pack (a publishing tool for npm package authors), Pika CI (a Github action that let you &lt;code&gt;npm install&lt;/code&gt; or even &lt;code&gt;import()&lt;/code&gt; any GitHub PR), a failed in-browser code editor, and a next-gen JavaScript CDN that went on become &lt;a href="https://www.skypack.dev/"&gt;Skypack.&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;The biggest standout of the bunch was @pika/web, which let you install any npm package to run directly in the browser without a bundler (ex: &lt;code&gt;react -&amp;gt; /react.js&lt;/code&gt;). You probably know this project better under its newer name: Snowpack.&lt;/p&gt;

&lt;p&gt;Below are five lessons that I learned while growing Snowpack from its first commit to the official v1.0 release, and how we found our first set of users.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson 1: Start with a personal frustration
&lt;/h2&gt;

&lt;p&gt;Snowpack began as a tool to convert any npm package to a single JavaScript file that you could run in the browser. Sounds boring, right? Wrong! &lt;/p&gt;

&lt;p&gt;This small, straightforward tool would unlock an &lt;a href="https://www.pika.dev/blog/pika-web-a-future-without-webpack"&gt;entirely new mode of web development&lt;/a&gt; that is now referred to as &lt;a href="https://www.youtube.com/watch?v=aee93s9TZVc"&gt;"Unbundled Web Development"&lt;/a&gt;. Unbundled development introduced features like instant reloads and near-instant startup time during development, using a process that wouldn't slow down as your project grows to 1,000 or even 10,000+ files. Compare this to more traditional bundled dev environments, where multi-second startup and reload times are still the norm today.&lt;/p&gt;

&lt;p&gt;The original idea for Snowpack came out of a simple, personal frustration that I had been having at work. I was working on the Polymer team at Google, where I had helped create some alterative build tools for the (now dead) &lt;a href="https://developer.mozilla.org/en-US/docs/Web/Web_Components/HTML_Imports"&gt;HTML Imports&lt;/a&gt; spec. The tool itself was lovely, but it didn't work well with npm and very few people ever used it.&lt;/p&gt;

&lt;p&gt;I eventually left the Polymer team, but that problem still stuck in my head: Why had bundlers like webpack become the only way to use npm packages in the browser? &lt;strong&gt;Something&lt;/strong&gt; has to solve the problem of getting npm packages to run in the browser, but did it have to involve bundling your entire website? Snowpack was my attempt to find out whether another path was possible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson for open source maintainers:&lt;/strong&gt; Build for yourself, first. If you're frustrated by something, chances are other developers are too. Question everything.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson 2: move fast, stay small
&lt;/h2&gt;

&lt;p&gt;When you're working on a new project, you rarely know what code will be important long-term and what code is about to be deleted. I've thrown away enough code in my career to have learned that there's sometimes value in fast, messy coding. When you're starting a new project, it's okay to be a bit messy.&lt;/p&gt;

&lt;p&gt;Internally, almost all of Snowpack's complexity was handled by Rollup. Snowpack was really just a wrapper around Rollup that would bundle only your npm packages instead of your entire website. Realizing that Snowpack could leverage Rollup internally saved me weeks (or maybe even months) of development time.&lt;/p&gt;

&lt;p&gt;To be honest, Snowpack was just &lt;a href="https://github.com/snowpackjs/snowpack/tree/6d596af2ee99c8c5fb0c4097283e50fe125d0a8f/src"&gt;a single &lt;code&gt;index.js&lt;/code&gt; file&lt;/a&gt; for the majority of its life. &lt;/p&gt;

&lt;p&gt;To keep the project on track, I focused on a single feature: "give me a package name, and I'll convert it to ESM."  This would be too low-level for most web developers. In fairness, Snowpack really didn't take off with a large audience until we added a built-in dev server and build command in v2.0. But even without the dev server, Snowpack's small v1.0 focus was enough for a certain kind of low-tooling/no-tooling web developer.&lt;/p&gt;

&lt;p&gt;My overeall recommendation is to test your idea and get together a working demo as quickly as possible. In practice, this means four things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Use existing tools!&lt;/strong&gt; Fork a similar open source project or use an existing tool internally if it can save you time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write messy code!&lt;/strong&gt; At the earliest stage, you probably don't know exactly know what you're building. Premature refactoring can sometimes be worse than never refactoring at all, so keep your code flexible for as long as possible.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep scope small!&lt;/strong&gt; Don't build half-baked, half-working features. Instead, focus on doing one thing very well.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Skip tests!&lt;/strong&gt; Confirm that you're building something useful before spending your free time writing tests for it. Nothing is worse than writing tests for something that you end up never using. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I know that some of this could be considered a hot/controversial take. "No testing??? Blasphemy!" All I can say is that this strategy has worked well for me over several popular projects and countless unpopular projects that went nowhere.&lt;/p&gt;

&lt;p&gt;The obvious downside to this "move fast" advise is that it is not sustainable long-term. Moving fast means taking on tech debt, which you will absolutely need to repay at some point &lt;em&gt;if your project becomes successful.&lt;/em&gt; As soon as you have some users who like what you're doing, you should begin to re-prioritize stability, refactoring and testing. More on this in the next post.&lt;/p&gt;

&lt;p&gt;Paying down tech debt can be a slog. But, silver lining: If your project never takes off, then congratulations! You didn't waste any time testing something that no one wanted :)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson for open source maintainers:&lt;/strong&gt; Write messy code, keep scope small, and skip any unnecessary work until you know that you're building something useful.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson 3: Fix fast
&lt;/h2&gt;

&lt;p&gt;You just received your first bug report. Oh no, someone tried your project out and it broke! But what matters is &lt;em&gt;that they cared enough to tell you about it.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;One of the best things that you can do in a new open source project is fix bug reports right as they come in. Prioritizing fixes over everything else becomes much harder as a project grows, so enjoy the freedom to move quickly while you still can.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/sebmck"&gt;Sebastian McKenzie&lt;/a&gt; (creator of Babel, Yarn, and now Rome) summarizes this theory well:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;One of the reasons Babel was successful is how quickly I was able to quickly fix bugs and release new versions. I would regularly have releases out within minutes of a bug report. This was critical during the early days when adoption was low. Being able to unblock users quickly would often make them more excited to use Babel even though they ran into a bug. -- &lt;a href="https://rome.tools/funding/#regularly-release-new-versions"&gt;Sebastian McKenzie, Rome&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Lesson for open source maintainers:&lt;/strong&gt; Your first users are essential. Prioritize fixing their issues over everything else.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson 4: Practice good storytelling
&lt;/h2&gt;

&lt;p&gt;Something about marketing always seems to make developers squeamish. Unfortunately, if you want people to use your project you eventually need to tell them about it. Even organic, viral word-of-mouth sensations tend to have a cheerleader acting behind-the-scenes.&lt;/p&gt;

&lt;p&gt;To start, just share your project with a friend or colleague and ask them for their thoughts. It's okay if you don't hit the front page of Hacker News on day one, all you're looking for is early feedback and maybe your first users.&lt;/p&gt;

&lt;p&gt;When you're ready to share your project with a larger audience, you have a few options for how to do it. One popular choice is to tell your story in small, visual pieces over time. This is how &lt;a href="https://twitter.com/sebmck/status/1108407803545214977"&gt;Sebastian built excitement for Rome&lt;/a&gt; for almost 2 years before its launch. &lt;a href="https://twitter.com/markdalgleish"&gt;Mark Dalgleish&lt;/a&gt; has also done a great job of promoting vanilla-extract on Twitter this way.&lt;/p&gt;

&lt;p&gt;You can also get creative, and do something unique. &lt;a href="https://twitter.com/BHolmesDev"&gt;Ben Holmes&lt;/a&gt; has been having a ton of fun recording announcement videos &lt;a href="https://twitter.com/BHolmesDev/status/1404426841440538627"&gt;in front of a whiteboard&lt;/a&gt; for his new project, &lt;a href="https://slinkity.dev/"&gt;Slinkity.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With Snowpack, I decided to tell our story in &lt;a href="https://www.pika.dev/blog/pika-web-a-future-without-webpack"&gt;one big blog post.&lt;/a&gt; This took some serious time to write, but gave us the space to really explain the "why" of the project. I figured that we had to make an emotion connection to our bigger goal to change the web. Even though this was just a single post, it made a big splash when it was released and then got re-shared and referenced over the next year.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson for open source maintainers:&lt;/strong&gt; Promote your work. Find a style of storytelling that fits you and your project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson 5: Ignore your haters, listen to your users
&lt;/h2&gt;

&lt;p&gt;If your work ever gets posted to Hacker News, expect some haters.&lt;/p&gt;

&lt;p&gt;If you're lucky, you can tell the difference between &lt;em&gt;ignorant criticism&lt;/em&gt; and &lt;em&gt;constructive criticism.&lt;/em&gt; Ignore the ignorant stuff (aka haters) but listen to the constructive feedback if you can. If someone shows that they took the time to at least attempt to understand your project &lt;strong&gt;in good faith&lt;/strong&gt;, their feedback will usually have some value if you can spot.&lt;/p&gt;

&lt;p&gt;A common constructive criticism is when someone clearly &lt;em&gt;tried&lt;/em&gt; understand your work, but still misunderstood some key part of it. It's easy to call that person dumb and move on, but remember that clear communication is your responsibility. When someone misunderstands your work, it usually means that you could improve your README or documentation or general storytelling in some way.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson for open source maintainers:&lt;/strong&gt; Haters gonna hate, ignore them. Learn how to spot the good-faith, constructive criticism.&lt;/p&gt;

&lt;h2&gt;
  
  
  Main Takeaway: Support your early users
&lt;/h2&gt;

&lt;p&gt;If you're starting a new open source project, the best thing that you can do is make sure that your first 10 users are happy. All of the lessons above are really just about finding and supporting these first users in some way. If you do right by them, then you've already built something meaningful.&lt;/p&gt;

&lt;p&gt;And if this all sounds like too much work, remember that open source software has no rules. It's supposed to be fun. Building for yourself or a smaller audience is totally fine, in which case you can go ahead and ignore most of this advice.&lt;/p&gt;

</description>
      <category>snowpack</category>
      <category>opensource</category>
      <category>javascript</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Introducing: Pika CDN + Deno</title>
      <dc:creator>Fred K. Schott</dc:creator>
      <pubDate>Wed, 05 Feb 2020 23:37:00 +0000</pubDate>
      <link>https://forem.com/pika/introducing-pika-cdn-deno-p8b</link>
      <guid>https://forem.com/pika/introducing-pika-cdn-deno-p8b</guid>
      <description>&lt;p&gt;&lt;a href="https://deno.land/" rel="noopener noreferrer"&gt;Deno&lt;/a&gt; isn't just for TypeScript, anymore! Did you know that you can also use Deno to import and run JavaScript packages from npm? &lt;/p&gt;

&lt;p&gt;As long as your package is written as &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules" rel="noopener noreferrer"&gt;ESM&lt;/a&gt; (JavaScript's native module syntax) and doesn't rely on any Node-specific behavior/imports, Deno can load and run JavaScript from any URL without breaking a sweat. Pika already hosts &lt;a href="https://www.pika.dev/search" rel="noopener noreferrer"&gt;a search catalog of 80,000+ ESM packages on npm&lt;/a&gt; with more being added every day. &lt;/p&gt;

&lt;p&gt;All of this makes the &lt;a href="https://www.pika.dev/cdn" rel="noopener noreferrer"&gt;Pika CDN&lt;/a&gt; -- our modern CDN for the npm ecosystem -- a great fit for Deno. With the Pika CDN, you can &lt;code&gt;import&lt;/code&gt; any npm package from a single, hosted URL. This has always been a good fit for websites, but now it is an even better fit for Deno. That's because Deno has no package manager, so importing packages from URLs is already built in to the Deno workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing "X-TypeScript-Types"
&lt;/h2&gt;

&lt;p&gt;But what about type declarations? Deno is a TypeScript runtime, after all. It would be a shame if you couldn't also fetch the type declarations that exist inside of each npm package (or via the community-generated &lt;code&gt;@types/&lt;/code&gt; project by DefinitelyTyped) whenever you import a JS npm package.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Well, now you can!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmg12ls44h2kg89p6lxfu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmg12ls44h2kg89p6lxfu.png" alt="Deno + Pika Example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In collaboration with the Deno team for their recent v0.32.0 release, Pika CDN now hosts type declarations for every package that provides them! Import an npm package from our CDN and Deno will automatically fetch its type declarations along with it. &lt;/p&gt;

&lt;p&gt;With this new feature, your programs get an extra level of stability with automatic warnings from Deno when a package is used incorrectly.&lt;/p&gt;

&lt;p&gt;This is all thanks to Deno's new "X-TypeScript-Types" response header support. Here's how it works:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Hosting the type declarations:&lt;/strong&gt; For Deno to read package type declarations, they have to exist somewhere on our CDN. We do the work at build-time to find the type files for your package and then host them at the &lt;code&gt;/types/*&lt;/code&gt; package URL subpath.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Telling Deno where to find them:&lt;/strong&gt; Each package on the CDN that has valid types responds with a &lt;code&gt;X-TypeScript-Types&lt;/code&gt; header. When Deno sees this header from an import, it automatically fetches the types and connects them to the import.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If no type declarations exist on npm, we don't send the header. In that case, Deno will read the JS files and make its best guess at what its interface looks like. We could try to do the same on the CDN, but for now we feel pretty confident that Deno is better at this than we are :)&lt;/p&gt;

&lt;h2&gt;
  
  
  Exciting Times!
&lt;/h2&gt;

&lt;p&gt;None of this would have been possible without the efforts of &lt;a href="https://twitter.com/kitsonk" rel="noopener noreferrer"&gt;@kitsonk&lt;/a&gt; and the entire team of &lt;a href="https://github.com/denoland/deno" rel="noopener noreferrer"&gt;Deno contributors&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;With these changes, &lt;a href="https://www.pika.dev/cdn" rel="noopener noreferrer"&gt;Pika CDN&lt;/a&gt; is now THE BEST PLACE to get npm packages that run on Deno. This is something that we're extremely proud of, and a goal that we'll keep improving on as Deno works towards their v1.0 release. Exciting times, indeed!&lt;/p&gt;

&lt;p&gt;We can't wait to see what you build with Deno and our CDN. &lt;a href="https://twitter.com/pikapkg" rel="noopener noreferrer"&gt;Reach out to us on Twitter&lt;/a&gt; with any questions, comments, and links to what you've built.&lt;/p&gt;

&lt;p&gt;✌️&lt;br&gt;
- &lt;a href="https://twitter.com/FredKSchott" rel="noopener noreferrer"&gt;@fks&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Tree-Shaking Without a Bundler? Here's How Snowpack Does It!</title>
      <dc:creator>Fred K. Schott</dc:creator>
      <pubDate>Thu, 16 Jan 2020 00:10:20 +0000</pubDate>
      <link>https://forem.com/pika/tree-shaking-without-a-bundler-here-s-how-snowpack-does-it-1fai</link>
      <guid>https://forem.com/pika/tree-shaking-without-a-bundler-here-s-how-snowpack-does-it-1fai</guid>
      <description>&lt;p&gt;Until &lt;a href="https://www.snowpack.dev/" rel="noopener noreferrer"&gt;Snowpack&lt;/a&gt; came on the scene, application bundling was the only way to do tree-shaking (dead-code elimination) on the web.&lt;/p&gt;

&lt;p&gt;But Snowpack is the unbundler. It runs only on your dependencies without ever touching your application code. So how could it tree-shake? &lt;/p&gt;

&lt;p&gt;Here's a quick post about how we made this production optimization happen for faster production apps, thanks to some essential help from the &lt;a href="http://rollupjs.org/" rel="noopener noreferrer"&gt;RollupJS&lt;/a&gt; team 🙌&lt;/p&gt;

&lt;h2&gt;
  
  
  The Setup
&lt;/h2&gt;

&lt;p&gt;Bundlers "tree-shake" your web application by finding and removing unused code, shaving off valuable bytes when you deploy to production.&lt;/p&gt;

&lt;p&gt;Since Snowpack never touches your application code, how could we do the same? We had to get creative. &lt;/p&gt;

&lt;p&gt;Snowpack v1.0 added an initial "scan" phase behind the &lt;code&gt;--optimize&lt;/code&gt; flag. It runs a quick scan of your app to learn how you use each dependency.&lt;/p&gt;

&lt;p&gt;... and that's it! We pass that info to our internal installer (powered by Rollup) and eliminate any dead code at install time. &lt;/p&gt;

&lt;h2&gt;
  
  
  The Challenge
&lt;/h2&gt;

&lt;p&gt;"Passing that info to our Rollup-powered installer" was an interesting challenge: How do you tell Rollup that code in your top-level entrypoints is unused?&lt;/p&gt;

&lt;p&gt;This was an unusual request, and something the Rollup team (rightfully!) didn't want to build into the bundler itself. &lt;/p&gt;

&lt;p&gt;We &lt;a href="https://github.com/rollup/rollup/issues/3047" rel="noopener noreferrer"&gt;created an issue&lt;/a&gt; on the Rollup repo to outline the problem, and with &lt;a href="https://twitter.com/lukastaegert" rel="noopener noreferrer"&gt;@lukastaegert&lt;/a&gt;'s help came up with a really clever solution via a new plugin...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fa3eipsbyqo9davqoyzny.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fa3eipsbyqo9davqoyzny.png" alt="issue screenshot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here's how we solved it:&lt;/strong&gt; We create an in-memory "envelope" wrapper for Rollup of every dep &amp;amp; fill it with the exact imports used by your app.&lt;/p&gt;

&lt;p&gt;Rollup sees the envelope, reads the scanned imports to the real dep, &amp;amp; then automatically tree-shakes out everything not found in the ✉️ &lt;br&gt;
You can see exactly how it works here, coming in at &lt;a href="https://github.com/pikapkg/snowpack/blob/a05263ab9bb22ae1f79fc084dd88d65cd462432c/src/rollup-plugin-treeshake-inputs.ts#L7-L12" rel="noopener noreferrer"&gt;only ~50 LOC&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fmrh8obkfxhj19wnktjz4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fmrh8obkfxhj19wnktjz4.png" alt="plugin screenshot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This all runs behind the production-only &lt;code&gt;--optimize&lt;/code&gt; flag, so you can add &amp;amp; remove imports as you develop your app without worrying about tree-shaking or needing to re-install as your code changes. &lt;/p&gt;

&lt;p&gt;But even when optimizing for production, just reading &amp;amp; scanning your application code should be a hell of a lot faster than reading, scanning AND BUNDLING your app code with a traditional bundler (so you can still expect fast production deployments).&lt;/p&gt;
&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;p&gt;We're experimenting with replacing our current import scanner with the even faster &lt;a href="https://github.com/guybedford/es-module-lexer" rel="noopener noreferrer"&gt;es-module-lexer&lt;/a&gt; by &lt;a href="https://twitter.com/guybedford" rel="noopener noreferrer"&gt;@guybedford&lt;/a&gt;, a WASM-powered scanner written in C.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/guybedford" rel="noopener noreferrer"&gt;
        guybedford
      &lt;/a&gt; / &lt;a href="https://github.com/guybedford/es-module-lexer" rel="noopener noreferrer"&gt;
        es-module-lexer
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Low-overhead lexer dedicated to ES module parsing for fast analysis
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;ES Module Lexer&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://github.com/guybedford/es-module-lexer/actions/workflows/build.yml" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/guybedford/es-module-lexer/actions/workflows/build.yml/badge.svg" alt="Build Status"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A JS module syntax lexer used in &lt;a href="https://github.com/guybedford/es-module-shims" rel="noopener noreferrer"&gt;es-module-shims&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Outputs the list of exports and locations of import specifiers, including dynamic import and import meta handling.&lt;/p&gt;
&lt;p&gt;Supports new syntax features including import attributes and source phase imports.&lt;/p&gt;
&lt;p&gt;A very small single JS file (4KiB gzipped) that includes inlined Web Assembly for very fast source analysis of ECMAScript module syntax only.&lt;/p&gt;
&lt;p&gt;For an example of the performance, Angular 1 (720KiB) is fully parsed in 5ms, in comparison to the fastest JS parser, Acorn which takes over 100ms.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Comprehensively handles the JS language grammar while remaining small and fast. - ~10ms per MB of JS cold and ~5ms per MB of JS warm, &lt;a href="https://github.com/guybedford/es-module-lexer#benchmarks" rel="noopener noreferrer"&gt;see benchmarks&lt;/a&gt; for more info.&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://github.com/guybedford/es-module-lexer/blob/main/chompfile.toml" rel="noopener noreferrer"&gt;Built with&lt;/a&gt; &lt;a href="https://chompbuild.com/" rel="nofollow noopener noreferrer"&gt;Chomp&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Usage&lt;/h3&gt;
&lt;/div&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;npm install es-module-lexer
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;See &lt;a href="https://github.com/guybedford/es-module-lexertypes/lexer.d.ts" rel="noopener noreferrer"&gt;types/lexer.d.ts&lt;/a&gt; for the type definitions.&lt;/p&gt;
&lt;p&gt;For use in CommonJS:&lt;/p&gt;
&lt;div class="highlight highlight-source-js notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-k"&gt;const&lt;/span&gt; &lt;span class="pl-kos"&gt;{&lt;/span&gt; init&lt;span class="pl-kos"&gt;,&lt;/span&gt; parse &lt;span class="pl-kos"&gt;}&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-en"&gt;require&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s"&gt;'es-module-lexer'&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-k"&gt;async&lt;/span&gt;&lt;/pre&gt;…
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/guybedford/es-module-lexer" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Thanks for Reading!
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Enjoyed this post?&lt;/strong&gt; Throw Snowpack a 🌟on GH to help spread the word:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/FredKSchott" rel="noopener noreferrer"&gt;
        FredKSchott
      &lt;/a&gt; / &lt;a href="https://github.com/FredKSchott/snowpack" rel="noopener noreferrer"&gt;
        snowpack
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      ESM-powered frontend build tool. Instant, lightweight, unbundled development. ✌️
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Update (April 20, 2022):&lt;/strong&gt; Snowpack is no longer actively maintained and is not recommended for new projects.&lt;/p&gt;
&lt;p&gt;Check out &lt;a href="https://vitejs.dev/" rel="nofollow noopener noreferrer"&gt;Vite&lt;/a&gt; for a well-maintained Snowpack alternative.&lt;br&gt;
See also: &lt;a href="https://esbuild.github.io/" rel="nofollow noopener noreferrer"&gt;esbuild&lt;/a&gt;, &lt;a href="https://parceljs.org/" rel="nofollow noopener noreferrer"&gt;parcel&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Snowpack&lt;/h1&gt;

&lt;/div&gt;
&lt;p&gt;Snowpack is a lightning-fast frontend build tool, designed to leverage JavaScript's native module system (&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import" rel="nofollow noopener noreferrer"&gt;known as ESM&lt;/a&gt;). It is an alternative to heavier, more complex bundlers like webpack or Parcel in your development workflow.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Key Features&lt;/h3&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Develop faster, with a dev server that starts up in &lt;strong&gt;50ms or less.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;See changes reflected &lt;a href="https://www.snowpack.dev/concepts/hot-module-replacement" rel="nofollow noopener noreferrer"&gt;instantly in the browser.&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Integrate your favorite bundler for a &lt;a href="https://www.snowpack.dev/concepts/build-pipeline" rel="nofollow noopener noreferrer"&gt;production-optimized build.&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Enjoy out-of-the-box support for &lt;a href="https://www.snowpack.dev/reference/supported-files" rel="nofollow noopener noreferrer"&gt;TypeScript, JSX, CSS Modules and more.&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Connect your favorite tools with &lt;a href="https://www.snowpack.dev/plugins" rel="nofollow noopener noreferrer"&gt;third-party plugins.&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;💁 More info at the official &lt;a href="https://snowpack.dev" rel="nofollow noopener noreferrer"&gt;Snowpack website ➞&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;br&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Contributor Guidelines:&lt;/strong&gt; &lt;a href="https://github.com/FredKSchott/snowpack./CONTRIBUTING.md" rel="noopener noreferrer"&gt;CONTRIBUTING.md&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;License:&lt;/strong&gt; &lt;a href="https://github.com/withastro/snowpack/blob/main/LICENSE" rel="noopener noreferrer"&gt;MIT&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/FredKSchott/snowpack" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;ul&gt;
&lt;li&gt;Learn more about Snowpack: &lt;a href="https://www.snowpack.dev/" rel="noopener noreferrer"&gt;https://www.snowpack.dev/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Follow us on Twitter for updates: &lt;a href="https://twitter.com/pikapkg" rel="noopener noreferrer"&gt;https://twitter.com/pikapkg&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Read &amp;amp; share the original Twitter thread that this was based on: &lt;a href="https://twitter.com/pikapkg/status/1217509391668133888" rel="noopener noreferrer"&gt;https://twitter.com/pikapkg/status/1217509391668133888&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>npm</category>
      <category>github</category>
      <category>productivity</category>
      <category>cicd</category>
    </item>
    <item>
      <title>Unrolled: Introducing the Pika REPL</title>
      <dc:creator>Fred K. Schott</dc:creator>
      <pubDate>Tue, 06 Aug 2019 16:24:51 +0000</pubDate>
      <link>https://forem.com/pika/unrolled-introducing-the-pika-repl-1pbh</link>
      <guid>https://forem.com/pika/unrolled-introducing-the-pika-repl-1pbh</guid>
      <description>&lt;p&gt;Today we launched the new rewrite of &lt;a href="https://www.pika.dev"&gt;pika.dev&lt;/a&gt;, which included a new &lt;a href="https://pika.dev/packages/async/repl"&gt;Package REPL&lt;/a&gt; for the package view page. This was just announced on Twitter, but I figured I'd unroll and repost the entire thread here quickly for anyone interested.&lt;/p&gt;

&lt;p&gt;You can read our entire release thread including all of todays releases here: &lt;a href="https://twitter.com/pikapkg/status/1158765492191911936"&gt;https://twitter.com/pikapkg/status/1158765492191911936&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What's a Package REPL? Keep reading to find out...&lt;/p&gt;


&lt;blockquote class="ltag__twitter-tweet"&gt;
      &lt;div class="ltag__twitter-tweet__media"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gzNPg-NC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/media/EBTINEQU8AAqkgX.jpg" alt="unknown tweet media content"&gt;
      &lt;/div&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--xwcYaZyy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/1138833988036902919/CFn7HVS6_normal.png" alt="Pika 📦 profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Pika 📦
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        @pikapkg
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P4t6ys1m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      ✨ INTRODUCING: The Pika Package REPL&lt;br&gt;&lt;br&gt;Test packages directly in the browser, without installing anything locally. Perfect for quickly evaluating packages before bringing them into your important projects.&lt;br&gt;&lt;br&gt;Try it today: &lt;a href="https://t.co/csuo48a64l"&gt;pika.dev/packages/path-…&lt;/a&gt; 
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      16:05 PM - 06 Aug 2019
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1158771146268872705" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-reply-action.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1158771146268872705" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-retweet-action.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      3
      &lt;a href="https://twitter.com/intent/like?tweet_id=1158771146268872705" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-like-action.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
      7
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;
&lt;br&gt;
&lt;blockquote class="ltag__twitter-tweet"&gt;
      &lt;div class="ltag__twitter-tweet__media"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lXwnfb8---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/media/EBTIOEGUwAEKCsi.jpg" alt="unknown tweet media content"&gt;
      &lt;/div&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--xwcYaZyy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/1138833988036902919/CFn7HVS6_normal.png" alt="Pika 📦 profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Pika 📦
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        @pikapkg
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P4t6ys1m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      True story: The second we had this feature working, we ended up needing it to quickly test our own site's path parsing logic. &lt;br&gt;&lt;br&gt;Instead of debugging the entire app, we could quickly iterate on just the code snippet... RIGHT IN THE BROWSER🤘 
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      16:05 PM - 06 Aug 2019
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1158771153244049409" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-reply-action.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1158771153244049409" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-retweet-action.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      0
      &lt;a href="https://twitter.com/intent/like?tweet_id=1158771153244049409" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-like-action.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
      0
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;
&lt;br&gt;
&lt;blockquote class="ltag__twitter-tweet"&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--xwcYaZyy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/1138833988036902919/CFn7HVS6_normal.png" alt="Pika 📦 profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Pika 📦
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        @pikapkg
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P4t6ys1m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      This is powered internally by ristretto: a really neat, modular testing library from the Polymer team.&lt;br&gt;&lt;br&gt;&lt;a href="https://t.co/5iUZc2W9J6"&gt;github.com/PolymerLabs/ri…&lt;/a&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      16:05 PM - 06 Aug 2019
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1158771156897259520" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-reply-action.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1158771156897259520" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-retweet-action.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      0
      &lt;a href="https://twitter.com/intent/like?tweet_id=1158771156897259520" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-like-action.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
      1
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;
&lt;br&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/PolymerLabs"&gt;
        PolymerLabs
      &lt;/a&gt; / &lt;a href="https://github.com/PolymerLabs/ristretto"&gt;
        ristretto
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      An extensible test runner ☕️
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;&lt;em&gt;🚨 &lt;strong&gt;PROJECT STATUS: EXPERIMENTAL&lt;/strong&gt; 🚨This product is in the Experimentation phase. Someone on the team thinks it’s an idea worth exploring, but it may not go any further than this. Use at your own risk.&lt;/em&gt;&lt;/p&gt;
&lt;h1&gt;
Ristretto&lt;/h1&gt;
&lt;p&gt;Ristretto is an extensible test runner.&lt;/p&gt;
&lt;p&gt;There are several established test runners in the JavaScript ecosystem
(&lt;a href="https://mochajs.org/" rel="nofollow"&gt;Mocha&lt;/a&gt;, &lt;a href="https://jasmine.github.io/" rel="nofollow"&gt;Jasmine&lt;/a&gt; and
&lt;a href="https://facebook.github.io/jest/" rel="nofollow"&gt;Jest&lt;/a&gt; to name a few of the more prominent
ones). Ristretto was created to address a feature sweet spot left unaddressed
by incumbent projects.&lt;/p&gt;
&lt;p&gt;Ristretto has the following qualities:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Simple, concise, class-based factorization&lt;/li&gt;
&lt;li&gt;Consumable as modules with browser-compatible path specifiers OOB&lt;/li&gt;
&lt;li&gt;Batteries included for the most popular testing syntaxes (BDD/TDD)&lt;/li&gt;
&lt;li&gt;Designed for extensibility (mixins, specialized reporters and a
spec-as-data-structure philosophy)&lt;/li&gt;
&lt;li&gt;Ships with mixins that enhance specs with powerful features (e.g., fixtures
and test isolation)&lt;/li&gt;
&lt;li&gt;Authored in TypeScript&lt;/li&gt;
&lt;li&gt;No build tooling required to use&lt;/li&gt;
&lt;li&gt;"JavaScript is the native language, The Web is the…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/PolymerLabs/ristretto"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;blockquote class="ltag__twitter-tweet"&gt;
      &lt;div class="ltag__twitter-tweet__media"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nBWHCdrm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/media/EBTIOppUIAEQKxB.jpg" alt="unknown tweet media content"&gt;
      &lt;/div&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--xwcYaZyy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/1138833988036902919/CFn7HVS6_normal.png" alt="Pika 📦 profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Pika 📦
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        @pikapkg
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P4t6ys1m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      Your code snippet is run as a fake ristretto "test", in a sandboxed iframe, directly in the browser.  Open up dev tools and you'll see any console output! 
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      16:05 PM - 06 Aug 2019
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1158771161993400320" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-reply-action.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1158771161993400320" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-retweet-action.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      0
      &lt;a href="https://twitter.com/intent/like?tweet_id=1158771161993400320" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-like-action.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
      1
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;
&lt;br&gt;
&lt;blockquote class="ltag__twitter-tweet"&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--xwcYaZyy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/1138833988036902919/CFn7HVS6_normal.png" alt="Pika 📦 profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Pika 📦
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        @pikapkg
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P4t6ys1m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      This is just the start, and we'll keep adding to this over the next few months! Two additions I can't wait for:&lt;br&gt;1⃣ Package type definitions &amp;amp; type checking&lt;br&gt;2⃣ Logging output/errors to the page if you're on mobile
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      16:15 PM - 06 Aug 2019
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1158773482504638466" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-reply-action.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1158773482504638466" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-retweet-action.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      0
      &lt;a href="https://twitter.com/intent/like?tweet_id=1158773482504638466" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-like-action.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
      0
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


&lt;p&gt;&lt;strong&gt;BONUS:&lt;/strong&gt; Curious about how a package works after using it in the REPL?&lt;/p&gt;


&lt;blockquote class="ltag__twitter-tweet"&gt;
      &lt;div class="ltag__twitter-tweet__media"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CU1wkr19--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/media/EBTPOf1U0AASmKb.jpg" alt="unknown tweet media content"&gt;
      &lt;/div&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--xwcYaZyy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/1138833988036902919/CFn7HVS6_normal.png" alt="Pika 📦 profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Pika 📦
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        @pikapkg
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P4t6ys1m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      The SOURCE tab is another incredibly useful, but subtle addition: An &lt;a href="https://twitter.com/unpkg"&gt;@unpkg&lt;/a&gt; browser built right in to the page. &lt;br&gt;&lt;br&gt;View any package source without leaving Pika, or click the link at the top to go directly to &lt;a href="https://t.co/CekBJwNeOl"&gt;unpkg.com&lt;/a&gt;. 
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      16:36 PM - 06 Aug 2019
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1158778858155331584" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-reply-action.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1158778858155331584" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-retweet-action.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      0
      &lt;a href="https://twitter.com/intent/like?tweet_id=1158778858155331584" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-like-action.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
      0
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


</description>
    </item>
    <item>
      <title>A Future Without Webpack</title>
      <dc:creator>Fred K. Schott</dc:creator>
      <pubDate>Fri, 02 Aug 2019 16:04:37 +0000</pubDate>
      <link>https://forem.com/pika/a-future-without-webpack-ago</link>
      <guid>https://forem.com/pika/a-future-without-webpack-ago</guid>
      <description>&lt;p&gt;&lt;em&gt;Note: This piece was originally published to &lt;a href="https://www.pika.dev/blog/pika-web-a-future-without-webpack" rel="noopener noreferrer"&gt;pika.dev&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The year is 1941. Your name is Richard Hubbell. You work at an experimental New York television studio owned by CBS. You are about to give one of the world's first major TV news broadcasts, with 15 minutes of airtime to fill. What do you do?&lt;/p&gt;

&lt;p&gt;In a world that has only known radio, you stick to what you know. That is, you read the news. "Most of the [televised] newscasts featured Hubbell reading a script with only occasional cutaways to a map or still photograph."&lt;sup&gt; &lt;a href="https://books.google.com/books?id=yWrEDQAAQBAJ&amp;amp;lpg=PA132&amp;amp;ots=WBn6zP9HAW&amp;amp;dq=newscasts%20featured%20Hubbell%20reading%20a%20script%20with%20only%20occasional%20cutaways&amp;amp;pg=PA132#v=onepage&amp;amp;q=newscasts%20featured%20Hubbell%20reading%20a%20script%20with%20only%20occasional%20cutaways&amp;amp;f=false" rel="noopener noreferrer"&gt;[1]&lt;/a&gt;&lt;/sup&gt; It would be a while before anyone would show actual video clips on the TV news.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fmrekui9j5l9de37smh9b.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fmrekui9j5l9de37smh9b.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As a JavaScript developer in 2019, I can relate. We have this new JavaScript module system &lt;a href="https://flaviocopes.com/es-modules/" rel="noopener noreferrer"&gt;(ESM)&lt;/a&gt; that runs natively on the web. Yet we continue to use bundlers for every single thing that we build. Why?&lt;/p&gt;

&lt;p&gt;Over the last several years, JavaScript bundling has morphed from a production-only optimization into a required build step for most web applications. Whether you love this or hate it, it's hard to deny that bundlers have added a ton of new complexity to web development -- a field of development that has always taken pride in its view-source, easy-to-get-started ethos.&lt;/p&gt;

&lt;p&gt;@pika/web is an attempt to free web development from the bundler requirement. &lt;strong&gt;In 2019, you should use a bundler because you want to, not because you need to.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fcm7c1to4rr2eq48x6ffe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fcm7c1to4rr2eq48x6ffe.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://twitter.com/stylishandy/status/1105049564237754373" rel="noopener noreferrer"&gt;Credit: 
 @stylishandy&lt;/a&gt;



&lt;h2&gt;
  
  
  Why We Bundle
&lt;/h2&gt;

&lt;p&gt;JavaScript bundling is a modern take on an old concept. Back in the day (lol ~6 years ago) it was common to minify and concatenate JavaScript files together in production. This would speed up your site and get around &lt;a href="https://stackoverflow.com/a/985704" rel="noopener noreferrer"&gt;HTTP/1.1's 2+ parallel request bottleneck&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;How did this nice-to-have optimization become an absolute dev requirement? Well, that's the craziest part: Most web developers never specifically asked for bundling. Instead, we got bundling as a side-effect of something else, something that we wanted realllllllly badly: &lt;strong&gt;npm.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://npmjs.com" rel="noopener noreferrer"&gt;npm&lt;/a&gt; -- which at the time stood for "Node.js Package Manager" -- was on its way to becoming the largest code registry ever created. Frontend developers wanted in on the action. The only problem was that its Node.js-flavored module system (Common.js or CJS) wouldn't run on the web without bundling. So Browserify, &lt;a href="https://webpack.js.org" rel="noopener noreferrer"&gt;Webpack&lt;/a&gt;, and the modern web bundler were all born.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.pika.dev%2Fstatic%2Fimg%2Fbundling-cra-graph-2.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.pika.dev%2Fstatic%2Fimg%2Fbundling-cra-graph-2.jpg"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://npm.anvaka.com/#/view/2d/react-scripts" rel="noopener noreferrer"&gt;Create React App visualized:&lt;/a&gt; 1,300 dependencies to run "Hello World"



&lt;h2&gt;
  
  
  Complexity Stockholm Syndrome
&lt;/h2&gt;

&lt;p&gt;Today, it's nearly impossible to build for the web without using a bundler like &lt;a href="https://webpack.js.org" rel="noopener noreferrer"&gt;Webpack&lt;/a&gt;. Hopefully, you use something like &lt;a href="https://facebook.github.io/create-react-app/" rel="noopener noreferrer"&gt;Create React App (CRA)&lt;/a&gt; to get started quickly, but even this will install a complex, 200.9MB &lt;code&gt;node_modules/&lt;/code&gt; directory of 1,300+ different dependencies just to run "Hello World!"&lt;/p&gt;

&lt;p&gt;Like Richard Hubbell, we are all so steeped in this world of bundlers that it's easy to miss how things could be different. We have these great, modern ESM dependencies now &lt;a href="https://dev.to/about/stats"&gt;(almost 50,000 on npm!)&lt;/a&gt;. What's stopping us from running them directly on the web?&lt;/p&gt;

&lt;p&gt;Well, a few things. 😕 It's easy enough to write web-native ESM code yourself, and it is true that some npm packages without dependencies can run directly on the web. Unfortunately, most will still fail to run. This can be due to either legacy dependencies of the package itself or the special way in which npm packages import dependencies by name.&lt;/p&gt;

&lt;p&gt;This is why @pika/web was created.&lt;/p&gt;

&lt;h2&gt;
  
  
  @pika/web: Web Apps Without the Bundler
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/FredKSchott" rel="noopener noreferrer"&gt;
        FredKSchott
      &lt;/a&gt; / &lt;a href="https://github.com/FredKSchott/snowpack" rel="noopener noreferrer"&gt;
        snowpack
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      ESM-powered frontend build tool. Instant, lightweight, unbundled development. ✌️
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Update (April 20, 2022):&lt;/strong&gt; Snowpack is no longer actively maintained and is not recommended for new projects.&lt;/p&gt;
&lt;p&gt;Check out &lt;a href="https://vitejs.dev/" rel="nofollow noopener noreferrer"&gt;Vite&lt;/a&gt; for a well-maintained Snowpack alternative.&lt;br&gt;
See also: &lt;a href="https://esbuild.github.io/" rel="nofollow noopener noreferrer"&gt;esbuild&lt;/a&gt;, &lt;a href="https://parceljs.org/" rel="nofollow noopener noreferrer"&gt;parcel&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Snowpack&lt;/h1&gt;

&lt;/div&gt;
&lt;p&gt;Snowpack is a lightning-fast frontend build tool, designed to leverage JavaScript's native module system (&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import" rel="nofollow noopener noreferrer"&gt;known as ESM&lt;/a&gt;). It is an alternative to heavier, more complex bundlers like webpack or Parcel in your development workflow.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Key Features&lt;/h3&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Develop faster, with a dev server that starts up in &lt;strong&gt;50ms or less.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;See changes reflected &lt;a href="https://www.snowpack.dev/concepts/hot-module-replacement" rel="nofollow noopener noreferrer"&gt;instantly in the browser.&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Integrate your favorite bundler for a &lt;a href="https://www.snowpack.dev/concepts/build-pipeline" rel="nofollow noopener noreferrer"&gt;production-optimized build.&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Enjoy out-of-the-box support for &lt;a href="https://www.snowpack.dev/reference/supported-files" rel="nofollow noopener noreferrer"&gt;TypeScript, JSX, CSS Modules and more.&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Connect your favorite tools with &lt;a href="https://www.snowpack.dev/plugins" rel="nofollow noopener noreferrer"&gt;third-party plugins.&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;💁 More info at the official &lt;a href="https://snowpack.dev" rel="nofollow noopener noreferrer"&gt;Snowpack website ➞&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;br&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Contributor Guidelines:&lt;/strong&gt; &lt;a href="https://github.com/FredKSchott/snowpack./CONTRIBUTING.md" rel="noopener noreferrer"&gt;CONTRIBUTING.md&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;License:&lt;/strong&gt; &lt;a href="https://github.com/withastro/snowpack/blob/main/LICENSE" rel="noopener noreferrer"&gt;MIT&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/FredKSchott/snowpack" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;&lt;a href="https://github.com/pikapkg/web" rel="noopener noreferrer"&gt;@pika/web&lt;/a&gt; installs modern npm dependencies in a way that lets them run natively in the browser, even if they have dependencies themselves. That's it. It's not a build tool and it's not a bundler (in the traditional sense, anyway). @pika/web is a dependency install-time tool that lets you dramatically reduce the need for other tooling and even skip &lt;a href="https://webpack.js.org" rel="noopener noreferrer"&gt;Webpack&lt;/a&gt; or &lt;a href="https://parceljs.org/" rel="noopener noreferrer"&gt;Parcel&lt;/a&gt; entirely.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npx @pika/web
✔ @pika/web installed web-native dependencies. &lt;span class="o"&gt;[&lt;/span&gt;0.41s]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;@pika/web checks your &lt;code&gt;package.json&lt;/code&gt; manifest for any &lt;code&gt;"dependencies"&lt;/code&gt; that export a valid ESM "module" entry point, and then installs them to a local &lt;code&gt;web_modules/&lt;/code&gt; directory. @pika/web works on any ESM package, even ones with ESM &amp;amp; Common.js internal dependencies.&lt;/p&gt;

&lt;p&gt;Installed packages run in the browser because @pika/web bundles each package into a single, web-ready ESM &lt;code&gt;.js&lt;/code&gt; file. For example: The entire "preact" package is installed to &lt;code&gt;web_modules/preact.js&lt;/code&gt;. This takes care of anything bad that the package may be doing internally, while preserving the original package interface.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"Ah ha!"&lt;/em&gt; you might say. &lt;em&gt;&lt;a href="https://twitter.com/TheLarkInn/status/1102462419366891522" rel="noopener noreferrer"&gt;"That just hides bundling in a different place!"&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exactly!&lt;/strong&gt; @pika/web leverages bundling internally to output web-native npm dependencies, which was the main reason that many of us started using bundlers in the first place!&lt;/p&gt;

&lt;p&gt;With @pika/web all the complexity of the bundler is internalized in a single install-time tool. You never need to touch another line of bundler configuration if you don't want to. But of course, you can continue to use whatever other tools you like: Beef up your dev experience (&lt;a href="https://babeljs.io/" rel="noopener noreferrer"&gt;Babel&lt;/a&gt;, &lt;a href="https://www.typescriptlang.org" rel="noopener noreferrer"&gt;TypeScript&lt;/a&gt;) or optimize how you ship in production (&lt;a href="https://webpack.js.org" rel="noopener noreferrer"&gt;Webpack&lt;/a&gt;, &lt;a href="https://rollupjs.org/" rel="noopener noreferrer"&gt;Rollup&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This is the entire point of @pika/web: Bundle because you want to, not because you need to.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.pika.dev%2Fstatic%2Fimg%2Fbundling-view-source.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.pika.dev%2Fstatic%2Fimg%2Fbundling-view-source.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://www.pika.dev/js/pages/SearchPage.js" rel="noopener noreferrer"&gt;"view-source" is back!&lt;/a&gt;



&lt;h2&gt;
  
  
  Performance
&lt;/h2&gt;

&lt;p&gt;Installing each dependency this way (as a single JS file) gets you one big performance boost over most bundler setups: dependency caching. When you bundle all of your dependencies together into a single large &lt;code&gt;vendor.js&lt;/code&gt; file, updating one dependency can force your users to re-download the entire bundle. Instead, with @pika/web, updating a single package won't bust the rest of the user's cache.&lt;/p&gt;

&lt;p&gt;@pika/web saves you from this entire class of performance footguns introduced by bundlers. &lt;a href="https://formidable.com/blog/2018/finding-webpack-duplicates-with-inspectpack-plugin/" rel="noopener noreferrer"&gt;Duplicated code across bundles&lt;/a&gt;, &lt;a href="https://medium.com/webpack/better-tree-shaking-with-deep-scope-analysis-a0b788c0ce77" rel="noopener noreferrer"&gt;slow first page load due to unused/unrelated code&lt;/a&gt;, &lt;a href="https://medium.com/@allanbaptista/the-problem-with-webpack-8a025268a761" rel="noopener noreferrer"&gt;gotchas and bugs across upgrades to Webpack's ecosystem&lt;/a&gt;... Entire articles and tools are devoted to solving these issues.&lt;/p&gt;

&lt;p&gt;To be clear, leaving your application source unbundled isn't all sunshine and roses, either. Large JavaScript files do compress better over the wire than smaller, more granular files. And while multiple smaller files load just as well over &lt;a href="https://developers.google.com/web/fundamentals/performance/http2/#request_and_response_multiplexing" rel="noopener noreferrer"&gt;HTTP/2&lt;/a&gt;, the browser loses time parsing before then making follow-up requests for imports.&lt;/p&gt;

&lt;p&gt;It all comes down to a tradeoff between performance, caching efficiency, and how much complexity you feel comfortable with. And again, this is the entire point of @pika/web: Add a bundler because it makes sense to your situation, not because you have no other choice.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.pika.dev%2Fstatic%2Fimg%2Fbundling-legos.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.pika.dev%2Fstatic%2Fimg%2Fbundling-legos.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Pika Web App Strategy
&lt;/h2&gt;

&lt;p&gt;@pika/web has completely changed our approach to web development. Here is the process we used to build &lt;a href="https://dev.to/"&gt;pika.dev&lt;/a&gt;, and how we recommend you build your next web application in 2019:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;For new projects, skip the bundler. Write you application using modern ESM syntax and use @pika/web to install npm dependencies that runs natively on the web. No tooling required.&lt;/li&gt;
&lt;li&gt;Add tooling as you go. Add &lt;a href="https://www.typescriptlang.org" rel="noopener noreferrer"&gt;TypeScript&lt;/a&gt; if you want a type system, add &lt;a href="https://babeljs.io/" rel="noopener noreferrer"&gt;Babel&lt;/a&gt; if you want to use experimental JavaScript features, and add &lt;a href="https://github.com/terser-js/terser" rel="noopener noreferrer"&gt;Terser&lt;/a&gt; if you want JS minification. After 6+ months, &lt;a href="https://dev.to/"&gt;pika.dev&lt;/a&gt; is still happily at this phase.&lt;/li&gt;
&lt;li&gt;When you feel the need &amp;amp; have the time, experiment by adding a simple bundler for your application source code. Performance test it. Is it faster on first page load? Second page load? If so, ship it!&lt;/li&gt;
&lt;li&gt;Keep optimizing your bundler config as your application grows.&lt;/li&gt;
&lt;li&gt;When you have enough money, hire a Webpack expert. Congratulations! If you have the resources to hire a Webpack expert you have officially made it.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>pika</category>
      <category>webpack</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>@pika/pack - Publish great npm packages.</title>
      <dc:creator>Fred K. Schott</dc:creator>
      <pubDate>Fri, 02 Aug 2019 16:03:59 +0000</pubDate>
      <link>https://forem.com/pika/pika-pack-publish-great-npm-packages-3dnh</link>
      <guid>https://forem.com/pika/pika-pack-publish-great-npm-packages-3dnh</guid>
      <description>&lt;p&gt;&lt;em&gt;Note: This piece was originally published to &lt;a href="https://www.pika.dev/blog/introducing-pika-pack/"&gt;pika.dev&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you've recently published a package to npm, you know how much work goes into a modern build process. Transpile JavaScript, compile TypeScript, convert ES Module syntax (ESM) to Common.js, configure your package.json manifest... and that's just the basics.&lt;/p&gt;

&lt;p&gt;What about web browsers and bundlers? Is your &lt;a href="https://github.com/marmelab/react-admin/issues/2204"&gt;package optimized for them&lt;/a&gt;? Can users load your package from &lt;a href="https://unpkg.com/"&gt;UNPKG&lt;/a&gt;? Does it include &lt;a href="https://codeburst.io/https-chidume-nnamdi-com-npm-module-in-typescript-12b3b22f0724"&gt;type definitions&lt;/a&gt; for VSCode &amp;amp; TypeScript users? Has it been &lt;a href="https://medium.com/@jdxcode/for-the-love-of-god-dont-use-npmignore-f93c08909d8d"&gt;stripped of all unnecessary files&lt;/a&gt; to be as small as possible? Your users care about these optimizations, but they all require even more knowledge, configuration, tooling, time and effort to get right.&lt;/p&gt;

&lt;h3&gt;
  
  
  @pika/pack builds amazing packages without the hassle:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Simple&lt;/strong&gt; ⚡️ Use pre-configured plugins to build your entire package.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexible&lt;/strong&gt; 🏋️‍♀️ Choose plugins and optimizations that match your needs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Holistic&lt;/strong&gt; ⚛️ Let us handle your code, assets, &lt;strong&gt;&lt;em&gt;and&lt;/em&gt;&lt;/strong&gt; package.json config.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Package Build Pipeline
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/pikapkg/pack"&gt;@pika/pack&lt;/a&gt; connects pre-configured plugins to build and optimize your package for you. Plugins wrap already-popular tools like &lt;a href="https://babeljs.io/"&gt;Babel&lt;/a&gt; and &lt;a href="https://rollupjs.org/"&gt;Rollup&lt;/a&gt; with options already optimized for npm. This lets @pika/pack build your package without much (if any) configuration required on your part.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;@pika/pack even creates and configures a package.json manifest for your package, automatically.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This works because &lt;a href="https://github.com/pikapkg/pack"&gt;@pika/pack&lt;/a&gt; builds your entire package: code, assets, and even package.json manifest. By building the entire package, you end up with a fully-built &lt;code&gt;pkg/&lt;/code&gt; directory, ready to publish. Entry points like "main", "module", "umd:main", "types", "unpkg", and even advanced options like "sideEffects" and "files" are all handled by your build plugins.&lt;/p&gt;

&lt;p&gt;Getting started is easy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 1. Install @pika/pack!&lt;/span&gt;
&lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;install&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;g&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;pika&lt;/span&gt;&lt;span class="sr"&gt;/pac&lt;/span&gt;&lt;span class="err"&gt;k
&lt;/span&gt;&lt;span class="c1"&gt;// 2. Add this to your package.json manifest:&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@pika/pack&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pipeline&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]},&lt;/span&gt;
&lt;span class="c1"&gt;// 3. Run @pika/pack!&lt;/span&gt;
&lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="nx"&gt;pack&lt;/span&gt; &lt;span class="nx"&gt;build&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;span&gt;😎 🆒&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;So now what? If you run &lt;code&gt;pack build&lt;/code&gt; with an empty pipeline, you'll get an empty package. That's not very useful.&lt;/p&gt;

&lt;p&gt;To get you started, here are our five favorite things to do with &lt;a href="https://github.com/pikapkg/pack"&gt;@pika/pack&lt;/a&gt;:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Publish Modern, ES2018 JavaScript By Default (1 Line)
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@pika/pack&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pipeline&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@pika/plugin-standard-pkg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;exclude&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;__tests__/**/*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}]&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The first plugin that most packages will use is &lt;a href="https://github.com/pikapkg/builders/tree/master/packages/plugin-standard-pkg"&gt;@pika/plugin-standard-pkg&lt;/a&gt;. This is our standard &lt;a href="https://github.com/pikapkg/builders#source-builders"&gt;"source" builder&lt;/a&gt; that builds any JavaScript &amp;amp; TypeScript source code to the latest ES2018 language spec.  TypeScript is supported by default, and any custom Babel plugins in your local &lt;code&gt;.babelrc&lt;/code&gt; will be used automatically (the plugin is powered by Babel internally).&lt;/p&gt;

&lt;p&gt;This gives the rest of our pipeline a standard ES2018 target to build from. BONUS: some of your users may support modern JavaScript, and can leverage this ES2018 distribution directly for a smaller, faster, less-bloated package.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Publish Node.js &amp;amp; Web-Optimized Builds (1 Line Each)
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@pika/pack&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pipeline&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@pika/plugin-standard-pkg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@pika/plugin-build-node&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@pika/plugin-build-web&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;After creating your modern ES2018 build, it becomes trivial to add Node.js- and web-optimized distributions to your package. &lt;a href="https://github.com/pikapkg/builders/tree/master/packages/plugin-build-node"&gt;@pika/plugin-build-node&lt;/a&gt; will transpile a Node.js-ready distribution to run on any supported Node.js version. &lt;a href="https://github.com/pikapkg/builders/tree/master/packages/plugin-build-web"&gt;@pika/plugin-build-web&lt;/a&gt; will build a more modern, ES module (ESM) distribution: optimized for bundlers and compiled to run on all browsers that support ESM syntax natively.&lt;/p&gt;

&lt;p&gt;Both plugins use Rollup internally, but you don't have to configure any bundler logic yourself. With just three lines of JSON you get a package that is fully optimized for the two most popular JS platforms. And because &lt;a href="https://github.com/pikapkg/pack"&gt;@pika/pack&lt;/a&gt; builds your entire package, your package.json manifest is automatically configured for you with "main", "module", and "esnext" entry points.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Automatically Generate TypeScript Definitions (1 Line)
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@pika/pack&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pipeline&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@pika/plugin-standard-pkg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@pika/plugin-build-node&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@pika/plugin-build-web&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@pika/plugin-build-types&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;With &lt;a href="https://github.com/pikapkg/pack"&gt;@pika/pack&lt;/a&gt;, every package automatically gets &lt;code&gt;.d.ts&lt;/code&gt; TypeScript definition files thanks to the &lt;a href="https://github.com/pikapkg/builders/tree/master/packages/plugin-build-types"&gt;@pika/plugin-build-types&lt;/a&gt; plugin. Even if you're writing JavaScript, this plugin will use TypeScript to automatically generate type definitions from your JavaScript &amp;amp; JSDoc!&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Publish WASM! Or Reason, or Rust, or C++, or... (1-2 Lines)
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@pika/pack&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pipeline&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@pika/plugin-wasm-assemblyscript&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@pika/plugin-wasm-bindings&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The pipeline concept is simple AND flexible. So flexible that your package source doesn't even need to be JavaScript:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/pikapkg/builders/tree/master/packages/plugin-source-bucklescript"&gt;@pika/plugin-source-bucklescript&lt;/a&gt; - Compile Reason or OCaml to ES2018 JavaScript via BuckleScript&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/pikapkg/builders/tree/master/packages/plugin-wasm-assemblyscript"&gt;@pika/plugin-wasm-assemblyscript&lt;/a&gt; - Compile TypeScript to WASM via AssemblyScript&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/pikapkg/builders/issues/1"&gt;@pika/plugin-wasm-emscripten&lt;/a&gt; - Compile C/C++ to WASM via Emscripten (Coming Soon!).&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/pikapkg/builders/tree/master/packages/plugin-wasm-bindings"&gt;@pika/plugin-wasm-bindings&lt;/a&gt; - Add simple JavaScript bindings for any generated WASM.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5. Automatically Enhance Your Package (1 Line)
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@pika/pack&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pipeline&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@pika/plugin-standard-pkg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@pika/plugin-build-node&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@pika/plugin-simple-bin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;my-cli&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Build plugins can also enhance existing builds in some really exciting ways. Our favorite enhancement right now is &lt;a href="https://github.com/pikapkg/builders/tree/master/packages/plugin-simple-bin"&gt;@pika/plugin-simple-bin&lt;/a&gt;, which injects a simple CLI wrapper into any package and configures your package.json to point to it automatically.&lt;/p&gt;

&lt;p&gt;We use @pika/pack to build @pika/pack, and we use this plugin specifically to &lt;a href="https://unpkg.com/@pika/pack@0.3.0/dist-node/index.bin.js"&gt;add a command-line interface&lt;/a&gt; with none of the package.json configuration and setup hassle.&lt;/p&gt;

&lt;p&gt;We can't wait to see what's possible with this wrapping concept, especially for CLIs: Automatically restart your program on failure, check for package updates after running, log usage statistics... &lt;a href="https://github.com/pikapkg/builders"&gt;the possibilities are endless!&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Publishing Your Package
&lt;/h2&gt;

&lt;p&gt;
  
    
    &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VKlR9MGc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://www.pika.dev/static/img/publish-demo.gif" class="article-body-image-wrapper"&gt;&lt;img alt="Demo" src="https://res.cloudinary.com/practicaldev/image/fetch/s--VKlR9MGc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://www.pika.dev/static/img/publish-demo.gif"&gt;&lt;/a&gt;
  
&lt;/p&gt;

&lt;p&gt;Publishing your package should be as easy as building it. So we brought our favorite parts of &lt;a href="https://github.com/sindresorhus/np"&gt;np&lt;/a&gt; (a self-described "better npm publish") into &lt;a href="https://github.com/pikapkg/pack"&gt;@pika/pack&lt;/a&gt;. With the &lt;code&gt;publish&lt;/code&gt; command there's no need to worry about how to publish your built package. Just run &lt;code&gt;pack publish&lt;/code&gt; in your top-level project and @pika/pack will walk you through cutting a new version and publishing your package.&lt;/p&gt;

&lt;p&gt;It even includes a handy &lt;a href="https://unpkg.com/"&gt;unpkg.com&lt;/a&gt; at the end so that you can immediately view your new package.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try @pika/pack Today!
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @pika/pack
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Don't wait, try &lt;a href="https://github.com/pikapkg/pack"&gt;@pika/pack&lt;/a&gt; in your next package (or any old ones that could a 2019 upgrade). And when you do, &lt;a href="https://twitter.com/pikapkg"&gt;please let us know how it went!&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/about"&gt;Pika&lt;/a&gt; is a project to move the JavaScript ecosystem forward. Pika's mission is to make modern JavaScript more approachable by making it easier to find, publish, install, and use modern packages on npm. Hopefully @pika/pack moves us one step closer towards that goal.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/about"&gt;Learn more about the Pika project →&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/pikapkg"&gt;Follow us on Twitter for updates →&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Projects Already Using @pika/pack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/ghengeveld/react-async"&gt;react-async&lt;/a&gt; - Flexible promise-based React data loader.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/michael-klein/hookuspocus"&gt;hookuspocus&lt;/a&gt; - hooks for all the functions!&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/jvdsande/foundationjs"&gt;foundationjs&lt;/a&gt; - Full-featured NodeJS framework.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/acro5piano/graphql-rest-proxy"&gt;graphql-rest-proxy&lt;/a&gt; - Turn your REST API into GraphQL.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/matthewp/custom-attributes"&gt;custom-attributes&lt;/a&gt; - Define custom attributes the same way you define custom elements.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/pikapkg/pack"&gt;@pika/pack&lt;/a&gt; &amp;amp; &lt;a href="https://github.com/pikapkg/web"&gt;@pika/web&lt;/a&gt; - yes, we even &lt;a href="https://github.com/pikapkg/pack/blob/1034a2f5a36ee8664ee139508f8726892534f65d/package.json#L6-L27"&gt;use @pika/pack&lt;/a&gt; to &lt;a href="https://unpkg.com/@pika/pack/package.json"&gt;build @pika/pack!&lt;/a&gt; 🤯&lt;/li&gt;
&lt;li&gt;And hundreds more! &lt;a href="https://github.com/pikapkg/examples"&gt;Check out our full set of example &amp;amp; starter projects →&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Have you used @pika/pack in a package? &lt;a href="https://twitter.com/pikapkg"&gt;Let us know&lt;/a&gt; and we'll add your package to the list!&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>pika</category>
      <category>npm</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
