<?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: Modern Web</title>
    <description>The latest articles on Forem by Modern Web (@modern-web).</description>
    <link>https://forem.com/modern-web</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%2Forganization%2Fprofile_image%2F2900%2Fdf186ddd-b018-4005-9f6f-4e0dc0d14652.png</url>
      <title>Forem: Modern Web</title>
      <link>https://forem.com/modern-web</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/modern-web"/>
    <language>en</language>
    <item>
      <title>Introducing check html links - no more bad links</title>
      <dc:creator>Thomas Allmer</dc:creator>
      <pubDate>Wed, 27 Jan 2021 11:59:33 +0000</pubDate>
      <link>https://forem.com/modern-web/introducing-check-html-links-no-more-bad-links-1jdg</link>
      <guid>https://forem.com/modern-web/introducing-check-html-links-no-more-bad-links-1jdg</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR : I created a standalone tool that can help you fix all the broken links in your websites/documentation. You can check it out &lt;a href="https://www.npmjs.com/package/check-html-links"&gt;on npm as check-html-links&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In my developer career, I have put live multiple websites and honestly often within a few days, there was always this one issue raised. "This link on xxx is broken". 🤦‍♂️&lt;/p&gt;

&lt;p&gt;Often these things happen as somewhere a page got moved or renamed and not every location got updated.&lt;br&gt;
It's really hard to catch especially if you have a dynamic page like with WordPress or an SPA. And for users, there is nothing worse than landing on your documentation only to find a 404 staring back at them.&lt;/p&gt;

&lt;p&gt;Luckily, with the rise of SSG (Static Site Generators), this problem becomes easier to tackle and can be solved in large part. The reason for that is that with all HTML rendered upfront as static files we can read all of them and check every link.&lt;/p&gt;
&lt;h2&gt;
  
  
  Evaluation and the decision for a new tool
&lt;/h2&gt;

&lt;p&gt;Of course, I am not the first one to come up with that idea and there are multiple tools available on the market already.&lt;br&gt;
However, when checking existing solutions I found out that most of them didn't satisfy me in at least on way 😅. Things I noticed: slow to execute, deprecated, large dependency tree, confusing output for the user, ...&lt;/p&gt;

&lt;p&gt;Reviewing these tools I decided to create my own, with the following requirements :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Blazing fast&lt;/li&gt;
&lt;li&gt;User-focused output&lt;/li&gt;
&lt;li&gt;Few dependencies, to keep it lean&lt;/li&gt;
&lt;li&gt;Preferably in the NodeJS ecosystem&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Focusing on Useful Output
&lt;/h2&gt;

&lt;p&gt;Most tools evaluated check files individually and report on their findings individually. That means if you have a broken link in your header or footer, you will get one line (or even multiple lines) of an error message(s) for EVERY page.&lt;/p&gt;

&lt;p&gt;I tested this on the &lt;a href="https://github.com/11ty/11ty-website"&gt;11ty-website&lt;/a&gt; and there are currently 516 broken links in 501 files. However, &lt;strong&gt;the source of those 516 broken links is just 13 missing pages/resources&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In my implementation, I decided to switch from an "Error in File Focused" method to a "Missing File Focused". Let's see this with examples&lt;/p&gt;
&lt;h3&gt;
  
  
  Error in File Focused
&lt;/h3&gt;

&lt;p&gt;This is what a lot of current existing solutions implement. Here is part of the output that is being produced:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[...]
authors/ryzokuken/index.html
  target does not exist --- authors/ryzokuken/index.html --&amp;gt; /speedlify/
authors/alex_kaul/index.html
  target does not exist --- authors/alex_kaul/index.html --&amp;gt; /speedlify/
docs/config/index.html
  target does not exist --- docs/config/index.html --&amp;gt; /speedlify/
  hash does not exist --- docs/config/index.html --&amp;gt; /docs/copy/#disabling-passthrough-file-copy
authors/cramforce/index.html
  target does not exist --- authors/cramforce/index.html --&amp;gt; /speedlify/
authors/accudio/index.html
  target does not exist --- authors/accudio/index.html --&amp;gt; /speedlify/
[...]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We get ~2000 lines of errors for &lt;code&gt;/speedlify/&lt;/code&gt; as it's not found ~500 times. In the middle of those errors, we also see some other broken links.&lt;br&gt;
Because the reporting is focusing first on the files, and then on the actual error &lt;strong&gt;it is difficult to know where most errors originate from&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Missing File Focused
&lt;/h3&gt;

&lt;p&gt;Let us turn that around and focus on missing references indeed. Here is the output for the same input website :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[...]
  1. missing reference target _site/speedlify/index.html
    from _site/404.html:1942:13 via href="/speedlify/"
    from _site/authors/_amorgunov/index.html:2031:13 via href="/speedlify/"
    from _site/authors/_coolcut/index.html:2031:13 via href="/speedlify/"
    ... 495 more references to this target

  2. missing id="disabling-passthrough-file-copy" in _site/docs/copy/index.html
    from _site/docs/config/index.html:2527:267 via href="/docs/copy/#disabling-passthrough-file-copy"

  3. missing reference target _site/authors/dkruythoff/github.com/dkruythoff/darius-codes
    from _site/authors/dkruythoff/index.html:2102:234 via href="github.com/dkruythoff/darius-codes"
[...]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We get one 5 line error for &lt;code&gt;/speedlify/&lt;/code&gt; and it tells us it's missing 495 times + 3 examples usages.&lt;br&gt;
Afterward, we find very clearly more missing references and where they occurred.&lt;/p&gt;
&lt;h3&gt;
  
  
  A clear winner
&lt;/h3&gt;

&lt;p&gt;Comparing those two outputs makes it pretty clear to me that &lt;code&gt;Missing File Focused&lt;/code&gt; will make more sense if there is a chance that some links will be broken everywhere. My implementation focuses on missing links in its output. This is crucial because it allows developers to know where to focus their efforts first to get the biggest wins.&lt;/p&gt;
&lt;h2&gt;
  
  
  Focusing on Speed
&lt;/h2&gt;

&lt;p&gt;Speed is always nice to have but in this case, it's probably vital. I need this to be fast so that I can run it potentially on every save. Speed is also very important in case the tool runs in a CI for example. For projects with extensive documentation, we don't want to hog the CI only to check for documentation.&lt;/p&gt;

&lt;p&gt;Luckily HTML is an awesome language to analyze as it's declarative, which means you can read and analyze it at the same time. This may even mean that the HTML is already processed by the time the file is done reading.&lt;/p&gt;

&lt;p&gt;With this knowledge I was hopeful - but reality didn't deliver 😅. The only tool that could keep up with the speed I needed was implemented in &lt;a href="https://golang.org/"&gt;Go&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It seems that most tools use sophisticated parsers meant to create full syntax trees of your HTML.&lt;br&gt;
In reality for link checking all you need to know are the &lt;em&gt;id&lt;/em&gt; and the &lt;em&gt;href&lt;/em&gt; attributes.&lt;/p&gt;

&lt;p&gt;I have been using &lt;a href="https://github.com/justinwilaby/sax-wasm"&gt;sax-wasm&lt;/a&gt; in a few situations before and I knew it supported streaming. I knew that way it could be FAST 🤞!&lt;/p&gt;

&lt;p&gt;How fast are we talking about though?&lt;/p&gt;

&lt;p&gt;As a rule of thumb, I decided that the analysis should be finished within 1s for a small site (up to 200 pages).&lt;br&gt;
The main reason is already listed above: To not disturb during writing/development as it will run on every save.&lt;br&gt;
For medium sites (200 - 1000 pages), it's reasonable if it takes a little longer - let's aim for less than 5 seconds. This will probably be a breaking point where you execute it only on-demand and in the CI instead of executing it on every save.&lt;/p&gt;

&lt;p&gt;Results are gatherd on January 26, 2021:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Website&lt;/th&gt;
&lt;th&gt;Pages&lt;/th&gt;
&lt;th&gt;Duration&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;open-wc.org&lt;/td&gt;
&lt;td&gt;90&lt;/td&gt;
&lt;td&gt;~0.4s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;11ty.dev&lt;/td&gt;
&lt;td&gt;501&lt;/td&gt;
&lt;td&gt;~2.5s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;web.dev&lt;/td&gt;
&lt;td&gt;830&lt;/td&gt;
&lt;td&gt;~3.7s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;eslint.org&lt;/td&gt;
&lt;td&gt;3475&lt;/td&gt;
&lt;td&gt;~12.4s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h2&gt;
  
  
  Being part of the NodeJS ecosystem
&lt;/h2&gt;

&lt;p&gt;My daily workflow is hugely dominated by JavaScript, so it was only natural to want to stay in the same environment if I could reach my earlier requirements with it.&lt;br&gt;
On top of this, the end goal is to integrate it within a bigger WIP system called &lt;a href="https://github.com/modernweb-dev/rocket"&gt;Rocket&lt;/a&gt; which is node-based so therefore it will need to at least support NodeJS. Having it standalone (usable via &lt;code&gt;npx&lt;/code&gt;) also makes it more versatile and easier to maintain/test.&lt;/p&gt;
&lt;h2&gt;
  
  
  Focusing on a small Dependency Tree
&lt;/h2&gt;

&lt;p&gt;The JavaScript and NodeJs ecosystem is very active and constantly shifting. Lots of changes/improvements happen all the time. It's often hard to keep up. Therefore having a small dependency tree is something to always thrive for because it will reduce the maintenance burden down the line. And as an added benefit, it makes it smaller and easily embeddable as less stuff has to go down the wire. Lean is king 👑.&lt;/p&gt;
&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;As already mentioned I went on and implement a link checker myself 😅. So far it fits all my requirements so I call it a success 🎉! You can find it &lt;a href="https://www.npmjs.com/package/check-html-links"&gt;on npm&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I called it &lt;code&gt;check-html-links&lt;/code&gt; and its slogan is "no more broken links or assets".&lt;/p&gt;

&lt;p&gt;The features so far are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;extracts every attribute value of id, href, src, srset&lt;/li&gt;
&lt;li&gt;use a wasm parser (sax-wasm)&lt;/li&gt;
&lt;li&gt;streams the html for performance&lt;/li&gt;
&lt;li&gt;check if file or id within file exist&lt;/li&gt;
&lt;li&gt;focus on missing references/sources&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;p&gt;It does check your final html output so you need to execute it after your Static Site Generator.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx check-html-links _site
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Usage Github Action
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://twitter.com/jlengrand"&gt;Julien&lt;/a&gt; created a Github action available for the tool, so you can easily plug it in your existing CI. You can find it &lt;a href="https://github.com/marketplace/actions/check-html-links-action"&gt;on the GitHub Marketplace&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here is a complete example workflow that will check the result of the folder &lt;code&gt;_site&lt;/code&gt; in the root of your repository on each push:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;check_html_links_job&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;A job to test check-html-links-action&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;check-html-links-action step&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;check-links&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;modernweb-dev/check-html-links-action@v1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;doc-folder&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;_site_'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Comparison
&lt;/h2&gt;

&lt;p&gt;Checking the output of &lt;a href="https://github.com/11ty/11ty-website"&gt;11ty-website&lt;/a&gt; with 13 missing reference targets (used by 516 links) while checking 501 files. (on January 17, 2021)&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Lines printed&lt;/th&gt;
&lt;th&gt;Duration&lt;/th&gt;
&lt;th&gt;Lang&lt;/th&gt;
&lt;th&gt;Dependency Tree&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;check-html-links&lt;/td&gt;
&lt;td&gt;38&lt;/td&gt;
&lt;td&gt;~2.5s&lt;/td&gt;
&lt;td&gt;node&lt;/td&gt;
&lt;td&gt;19&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;link-checker&lt;/td&gt;
&lt;td&gt;3000+&lt;/td&gt;
&lt;td&gt;~11s&lt;/td&gt;
&lt;td&gt;node&lt;/td&gt;
&lt;td&gt;106&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;hyperlink&lt;/td&gt;
&lt;td&gt;68&lt;/td&gt;
&lt;td&gt;4m 20s&lt;/td&gt;
&lt;td&gt;node&lt;/td&gt;
&lt;td&gt;481&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;htmltest&lt;/td&gt;
&lt;td&gt;1000+&lt;/td&gt;
&lt;td&gt;~0.7s&lt;/td&gt;
&lt;td&gt;GO&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Future
&lt;/h2&gt;

&lt;p&gt;The basic functionality is finished and it's reasonabley fast.&lt;/p&gt;

&lt;p&gt;Topic to work on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Allow to ignore folders (potentially via a cli parameter)&lt;/li&gt;
&lt;li&gt;Support for &lt;code&gt;&amp;lt;base href="/"&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Big Sites Speed improvements (potentially running multiple parsers in parallel for 1000+ pages)&lt;/li&gt;
&lt;li&gt;Speed improvements by introducing a "permanent cache" for the parse result (if file did not change, parse result will not change - we still check all links)&lt;/li&gt;
&lt;li&gt;Memory consumption check (see if there is room for improvements)&lt;/li&gt;
&lt;li&gt;Improve node api&lt;/li&gt;
&lt;li&gt;Check external links&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Acknowledgements
&lt;/h2&gt;

&lt;p&gt;Thank you for following along on my journey on creating &lt;code&gt;check-html-links&lt;/code&gt;. You can find the code on &lt;a href="https://github.com/modernweb-dev/rocket/tree/main/packages/check-html-links"&gt;Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Follow us on &lt;a href="https://twitter.com/modern_web_dev"&gt;Twitter&lt;/a&gt;, or follow me on my personal &lt;a href="https://twitter.com/dakmor"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thanks to &lt;a href="https://twitter.com/jlengrand"&gt;Julien&lt;/a&gt; for feedback and helping turn my scribbles to a followable story.&lt;/p&gt;

&lt;p&gt;If you think my open source work is valuable then I would like you to check out my personal &lt;a href="https://github.com/sponsors/daKmoR"&gt;Github Sponsor Page&lt;/a&gt;. Or you can support our whole group via the &lt;a href="https://opencollective.com/modern-web"&gt;Modern Web Open Collective&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;span&gt;Photo by &lt;a href="https://unsplash.com/@mihaiteslariu0?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Teslariu Mihai&lt;/a&gt; on &lt;a href="https://unsplash.com/?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

</description>
      <category>html</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>node</category>
    </item>
    <item>
      <title>Introducing: Modern Web</title>
      <dc:creator>Modern Web</dc:creator>
      <pubDate>Thu, 27 Aug 2020 00:00:00 +0000</pubDate>
      <link>https://forem.com/modern-web/introducing-modern-web-ab1</link>
      <guid>https://forem.com/modern-web/introducing-modern-web-ab1</guid>
      <description>&lt;p&gt;We are excited to finally introduce our brand new project: Modern Web.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Modern Web?
&lt;/h2&gt;

&lt;p&gt;A few years ago we started the &lt;a href="https://open-wc.org/"&gt;Open Web Components&lt;/a&gt; project. Our goal was to help people develop web components, and we created guides and tools to help people do this. While working on this project, we realized that a lot of the things we were making were not necessarily specific to web components.&lt;/p&gt;

&lt;p&gt;To maintain focus within the Open Web Components project, and to share our work with the larger developer community, we decided to split up the project and create Modern Web. Don't worry, Open Web Components is not going away! It will gain a renewed focus for web component specific topics, while in Modern Web we will work on generic tools and guides for web development.&lt;/p&gt;

&lt;h2&gt;
  
  
  The goal for Modern Web
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Our goal is to provide developers with the guides and tools they need to build for the modern web. We aim to work closely with the browser and avoid complex abstractions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Modern browsers are a powerful platform for building websites and applications. We try to work with what's available in the browser first before reaching for custom solutions.&lt;/p&gt;

&lt;p&gt;When you're working &lt;em&gt;with&lt;/em&gt; the browser rather than against it, code, skills, and knowledge remain relevant for a longer time. Development becomes faster and debugging is easier because there are fewer layers of abstraction involved.&lt;/p&gt;

&lt;p&gt;At the same time, we are aware of the fact that not all problems can be solved elegantly by the browser today. We support developers making informed decisions about introducing tools and customizations to their projects, in such a way that developers can upgrade later as browser support improves.&lt;/p&gt;

&lt;h2&gt;
  
  
  Our plan for the future
&lt;/h2&gt;

&lt;p&gt;This announcement marks the official release of Modern Web. Our website is live at &lt;a href="https://modern-web.dev"&gt;modern-web.dev&lt;/a&gt;, and our packages are available on NPM under the &lt;a href="https://www.npmjs.com/org/web"&gt;@web&lt;/a&gt; namespace. Our code is open-source and publicly available at &lt;a href="https://github.com/modernweb-dev/web"&gt;github.com/modernweb-dev/web&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For updates, you can follow us on &lt;a href="https://twitter.com/modern_web_dev"&gt;Twitter&lt;/a&gt;, and if you like what you see please consider sponsoring the project on &lt;a href="https://opencollective.com/modern-web"&gt;Open Collective&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We have been working on a lot of different projects in the last couple of years. In this post, we will walk you through some of our projects and how we are planning to fit them into the Modern Web project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Guides
&lt;/h2&gt;

&lt;p&gt;On our all-new &lt;a href="https://modern-web.dev"&gt;website&lt;/a&gt;, we have a dedicated &lt;a href="//../../guides/index.md"&gt;Guides&lt;/a&gt; section. It is meant to help you become confident in building for the modern web. It features step by step guides to work with our tools, and we document common issues developers run into when doing buildless development.&lt;/p&gt;

&lt;p&gt;This section is a work in progress, we're looking to add more over time and would love your feedback and improvements. Feel free to hit "Edit this page on GitHub!", &lt;a href="https://github.com/modernweb-dev/web/issues/new"&gt;open issues&lt;/a&gt; or &lt;a href="https://github.com/modernweb-dev/web/discussions"&gt;join the discussions&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Web Test Runner
&lt;/h2&gt;

&lt;p&gt;We are very excited to announce &lt;a href="//../../docs/test-runner/overview.md"&gt;web test runner&lt;/a&gt;, one of the major projects we have been working on for the past months.&lt;/p&gt;

&lt;p&gt;There are already a lot of testing solutions out there today. Unfortunately, all of them either run tests in Node.js and mock browser APIs using something like JSDom, or they don't support native es modules out of the box.&lt;/p&gt;

&lt;p&gt;We think that making browser code compatible for testing in node is unnecessarily complex. Running tests in real browsers give greater confidence in (cross-browser) compatibility and makes writing and debugging tests more approachable.&lt;/p&gt;

&lt;p&gt;That's why we created web test runner.&lt;/p&gt;

&lt;h3&gt;
  
  
  Highlights
&lt;/h3&gt;

&lt;p&gt;Some of the highlights of our test runner:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Headless testing using &lt;a href="//../../docs/test-runner/browser-launchers/puppeteer.md"&gt;Puppeteer&lt;/a&gt;, &lt;a href="//../../docs/test-runner/browser-launchers/playwright.md"&gt;Playwright&lt;/a&gt;, or &lt;a href="//../../docs/test-runner/browser-launchers/selenium.md"&gt;Selenium&lt;/a&gt;. 
&lt;/li&gt;
&lt;li&gt;Reports logs, 404s, and errors from the browser.&lt;/li&gt;
&lt;li&gt;Debug opens a real browser window with devtools.&lt;/li&gt;
&lt;li&gt;Mock ES modules via &lt;a href="//../../docs/test-runner/writing-tests/mocking.md"&gt;Import Maps&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Exposes browser properties like viewport size and dark mode.&lt;/li&gt;
&lt;li&gt;Runs tests in parallel and isolation.&lt;/li&gt;
&lt;li&gt;Interactive watch mode.&lt;/li&gt;
&lt;li&gt;Fast development by rerunning only changed tests.&lt;/li&gt;
&lt;li&gt;Powered by &lt;a href="//../../docs/dev-server/plugins/esbuild.md"&gt;esbuild&lt;/a&gt; and &lt;a href="//../../docs/dev-server/plugins/rollup.md"&gt;rollup plugins&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Getting started
&lt;/h3&gt;

&lt;p&gt;There is a beta version of the test runner available today on NPM as &lt;code&gt;@web/test-runner&lt;/code&gt;. It is almost feature-complete, we will have a v1 release soon!&lt;/p&gt;

&lt;p&gt;If you want get started now take a look at our Web Test Runner &lt;a href="//../../guides/test-runner/getting-started.md"&gt;Getting Started Guide&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Web Dev Server
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;es-dev-server&lt;/code&gt; is the most popular package at Open Web Components, but it is not specific to web components alone. That's why we're working on its spiritual successor in the modern web project. We will call it web dev server, and it will be published as &lt;code&gt;@web/dev-server&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you're doing buildless development, you can use any web server for development. Our dev server helps out by providing developer productivity features and making your code compatible with older browsers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Highlights
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Acts like a real web server, without any flags it serves code untransformed to the browser.&lt;/li&gt;
&lt;li&gt;Efficient caching of unchanged files between reloads.&lt;/li&gt;
&lt;li&gt;Resolve bare module imports using &lt;code&gt;--node-resolve&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Auto reload on file changes with &lt;code&gt;--watch&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Compatibility with older browsers using &lt;code&gt;--esbuild-target&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Extensive &lt;a href="//../../docs/dev-server/plugins/overview.md"&gt;plugin system&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Integration with &lt;a href="//../../docs/dev-server/plugins/esbuild.md"&gt;esbuild&lt;/a&gt; for fast transformation of JS, TS and JSX.&lt;/li&gt;
&lt;li&gt;Reuse most &lt;a href="//../../docs/dev-server/plugins/rollup.md"&gt;rollup plugins&lt;/a&gt; in the dev server.&lt;/li&gt;
&lt;li&gt;Plugin for polyfilling &lt;a href="//../../docs/dev-server/plugins/import-maps.md"&gt;Import maps&lt;/a&gt; during development.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Our web dev server is not quite finished &lt;em&gt;yet&lt;/em&gt;, but we've already built the basic parts to power our web test runner. This means that many of the listed features and plugins apply to our test runner as well.&lt;/p&gt;

&lt;p&gt;We are working hard on finalizing the open tasks on web dev server so stay tuned for further updates.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building for production
&lt;/h2&gt;

&lt;p&gt;While we try to avoid complex builds during development, they are still a requirement for production optimizations. Here too things can get pretty complex. Through plugins and guides, we will make it easier to integrate production builds with buildless development workflows.&lt;/p&gt;

&lt;p&gt;A good example here is &lt;a href="https://www.npmjs.com/package/@open-wc/rollup-plugin-html"&gt;@open-wc/rollup-plugin-html&lt;/a&gt; which we will move into the &lt;code&gt;@web&lt;/code&gt; namespace. This plugin enables running rollup on an existing HTML page. Rollup will bundle and optimize any modules scripts found in the HTML. It works with single pages, but also with multiple pages, code-splitting and sharing common code between pages.&lt;/p&gt;

&lt;p&gt;We plan to expand on this plugin further, adding support for optimizing assets such as images and CSS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Progressive web apps
&lt;/h2&gt;

&lt;p&gt;When we talk about modern web apps, we also talk about &lt;em&gt;progressive&lt;/em&gt; web apps (PWA). PWAs are a great way to provide an engaging and user-friendly experience for your user, by allowing your app to work offline, and being able to install your web app on the user's home screen, among many other benefits.&lt;/p&gt;

&lt;p&gt;Unfortunately, service workers are close to rocket science, and implementing PWA features isn't always as straightforward as it could be. That's why we'll provide technical guides and tools to make your life as a developer easier.&lt;/p&gt;

&lt;p&gt;Not only do we ship &lt;a href="https://www.npmjs.com/search?q=rollup-plugin-workbox"&gt;rollup-plugin-workbox&lt;/a&gt; to help you generate your service worker at build time, in the future, we will also have a set of zero dependency pwa-helpers as web components and vanilla javascript functions, as well as codelabs to help you get started building your modern, progressive web apps.&lt;/p&gt;

&lt;h2&gt;
  
  
  Documentation (rocket)
&lt;/h2&gt;

&lt;p&gt;In the past years, we've used different frameworks and tools to build our websites. Recently we've become big fans of &lt;a href="https://www.11ty.dev/"&gt;11ty&lt;/a&gt;. It's simple to use, works with markdown, and generates &lt;em&gt;just&lt;/em&gt; plain HTML. There is no runtime javascript involved to display page content, making it super fast.&lt;/p&gt;

&lt;p&gt;To add interactivity to our page we started using web components and applied rollup with our plugins for &lt;a href="https://www.npmjs.com/package/@open-wc/rollup-plugin-html"&gt;HTML&lt;/a&gt; and &lt;a href="https://www.npmjs.com/search?q=rollup-plugin-workbox"&gt;workbox&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This way our javascript is optimized and common code is shared between pages. Workbox adds a service worker, making our website available offline and precaches pages resulting is super fast navigation.&lt;/p&gt;

&lt;p&gt;For a great content authoring experience, we integrated 11ty with our dev server. This adds features like resolving bare imports, and reloading the browser when files change.&lt;/p&gt;

&lt;p&gt;By combining existing tools in this way, we think we've made something very powerful that will be useful for other people as well. That's why we started a child project in the modern web family, which we codenamed Rocket.&lt;/p&gt;

&lt;p&gt;It's still in its early stages, but we're already using a prototype for our own &lt;a href="https://modern-web.dev"&gt;website&lt;/a&gt;. We're still missing some features, but we'll continue to evolve it, and an announcement will follow as soon as it's finished. So keep an eye out for it!&lt;/p&gt;

&lt;h2&gt;
  
  
  Modern Web Family
&lt;/h2&gt;

&lt;p&gt;Welp, that was a lot of information for a first announcement post — we realize, but many of these projects have been years in the making, and are finally finding their right home. As we mentioned before, Modern Web is all about making the life of developers easier, reducing the complexity of tools, and staying close to the browser.&lt;/p&gt;

&lt;p&gt;While we have now spread out over multiple repositories like Open Web Components, Modern Web, and Rocket, we'd like to assure you that all of these projects fall under the same Modern Web Family, and aim to help make your life as developers easier.&lt;/p&gt;

&lt;h2&gt;
  
  
  Thanks for reading
&lt;/h2&gt;

&lt;p&gt;We are incredibly proud of what we have achieved so far and the direction we are heading and we invite you to join us on our path forward.&lt;/p&gt;

&lt;p&gt;There is much, much more to come so follow us on &lt;a href="https://twitter.com/modern_web_dev"&gt;Twitter&lt;/a&gt; and if you like what you see please consider sponsoring the project on &lt;a href="https://opencollective.com/modern-web"&gt;Open Collective&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Written with ♥️ by the Modern Web Core Team&lt;/p&gt;




&lt;p&gt;&lt;span&gt;Photo by &lt;a href="https://unsplash.com/@lemonvlad"&gt;Vladislav Klapin&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/hello"&gt;Unsplash&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>opensource</category>
      <category>modernweb</category>
    </item>
  </channel>
</rss>
