<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title>KHTDR – khtdr home page</title><description/><link>https://khtdr.com/</link><lastBuildDate>Mon, 14 Feb 2022 00:00:00 +0000</lastBuildDate><language>en-us</language><atom:link href="https://khtdr.com/index.xml" rel="self" type="application/rss+xml"/><item><title>css-vars-design-token</title><description> CSS Variables as Design Tokens: A Simple Approach to Design Systems Design systems are essential in modern web development. They help maintain consistency, speed up development, and ensure a cohesive user experience across applications. For small teams or even solo developers, a design system can really make things easier. It cuts down on repeated design decisions by providing reusable components and design guidelines and allowing developers to focus on building features instead of worrying about inconsistencies. This leads to faster iterations, easier onboarding for new team members, and a more unified product.</description><link>https://khtdr.com/css-vars-design-token.html</link><guid>https://khtdr.com/css-vars-design-token.html</guid><pubDate>Mon, 28 Oct 2024 00:00:00 +0000</pubDate><category>Software</category><content:encoded>
&lt;![CDATA[
&lt;div id="outline-container-headline-1" class="outline-2">
&lt;h2 id="headline-1">
CSS Variables as Design Tokens: A Simple Approach to Design Systems
&lt;/h2>
&lt;div id="outline-text-headline-1" class="outline-text-2">
&lt;p>
Design systems are essential in modern web development. They help maintain consistency, speed up development, and ensure a cohesive user experience across applications. For small teams or even solo developers, a design system can really make things easier. It cuts down on repeated design decisions by providing reusable components and design guidelines and allowing developers to focus on building features instead of worrying about inconsistencies. This leads to faster iterations, easier onboarding for new team members, and a more unified product.&lt;/p>
&lt;p>
CSS variables, or custom properties, are entities defined by CSS that let you store values for reuse throughout a document. They enable dynamic styling and can be updated at runtime, making them a powerful tool for creating flexible and maintainable design systems.&lt;/p>
&lt;/div>
&lt;/div>
&lt;div id="outline-container-headline-2" class="outline-2">
&lt;h2 id="headline-2">
Why CSS Variables Are Good Enough
&lt;/h2>
&lt;div id="outline-text-headline-2" class="outline-text-2">
&lt;p>
While there are many sophisticated design token solutions available, native CSS variables have evolved to be remarkably capable:&lt;/p>
&lt;ul>
&lt;li>They&amp;#39;re built into the platform&lt;/li>
&lt;li>They cascade naturally through the DOM&lt;/li>
&lt;li>They can be updated dynamically&lt;/li>
&lt;li>They work with any framework (or no framework)&lt;/li>
&lt;li>They&amp;#39;re performant&lt;/li>
&lt;li>Browser support is excellent&lt;/li>
&lt;/ul>
&lt;/div>
&lt;/div>
&lt;div id="outline-container-headline-3" class="outline-2">
&lt;h2 id="headline-3">
Introducing css-vars-design-token
&lt;/h2>
&lt;div id="outline-text-headline-3" class="outline-text-2">
&lt;p>
The &lt;code class="verbatim">css-vars-design-token&lt;/code> package offers a lightweight approach to design tokens using CSS variables. It provides:&lt;/p>
&lt;ol>
&lt;li>Simple theme switching&lt;/li>
&lt;li>TypeScript support&lt;/li>
&lt;li>React integration&lt;/li>
&lt;li>Zero dependencies beyond React itself&lt;/li>
&lt;/ol>
&lt;div id="outline-container-headline-4" class="outline-3">
&lt;h3 id="headline-4">
Basic Usage
&lt;/h3>
&lt;div id="outline-text-headline-4" class="outline-text-3">
&lt;p>
Here&amp;#39;s a simple example:&lt;/p>
&lt;div class="src src-javascript">
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Create the `light` and `dark` themes.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="kr">const&lt;/span> &lt;span class="nx">themes&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">light&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">color&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">primary&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;#0066cc&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">background&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;#ffffff&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">text&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;#333333&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">dark&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">color&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">primary&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;#66b3ff&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">background&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;#1a1a1a&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">text&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;#ffffff&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Wrap your components in a provider
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="kd">function&lt;/span> &lt;span class="nx">App&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">&amp;lt;&lt;/span>&lt;span class="nx">CssVarsDesignTokenProvider&lt;/span> &lt;span class="nx">themes&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="nx">themes&lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">&amp;lt;&lt;/span>&lt;span class="nx">MyComponents&lt;/span> &lt;span class="o">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">&amp;lt;&lt;/span>&lt;span class="err">/CssVarsDesignTokenProvider&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/div>
&lt;p>
Your CSS can then use these tokens:&lt;/p>
&lt;div class="src src-css">
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-css" data-lang="css">&lt;span class="line">&lt;span class="cl">&lt;span class="p">.&lt;/span>&lt;span class="nc">button&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">background-color&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="nf">var&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">--&lt;/span>&lt;span class="kc">color&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">primary&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">color&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="nf">var&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">--&lt;/span>&lt;span class="kc">color&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="kc">text&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">.&lt;/span>&lt;span class="nc">card&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">background-color&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="nf">var&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">--&lt;/span>&lt;span class="kc">color&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">background&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">border&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="kt">px&lt;/span> &lt;span class="kc">solid&lt;/span> &lt;span class="nf">var&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">--&lt;/span>&lt;span class="kc">color&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">primary&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/div>
&lt;/div>
&lt;/div>
&lt;div id="outline-container-headline-5" class="outline-3">
&lt;h3 id="headline-5">
Advanced Features
&lt;/h3>
&lt;div id="outline-text-headline-5" class="outline-text-3">
&lt;div id="outline-container-headline-6" class="outline-4">
&lt;h4 id="headline-6">
Deep Tokens
&lt;/h4>
&lt;div id="outline-text-headline-6" class="outline-text-4">
&lt;p>
The library automatically flattens deep token structures:&lt;/p>
&lt;div class="src src-javascript">
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="kr">const&lt;/span> &lt;span class="nx">themes&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">light&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">spacing&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">small&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;0.5rem&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">medium&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;1rem&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">large&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">default&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;2rem&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">mobile&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;1.5rem&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/div>
&lt;p>
This creates CSS variables like &lt;code class="verbatim">--spacing-small&lt;/code>, &lt;code class="verbatim">--spacing-medium&lt;/code>, &lt;code class="verbatim">--spacing-large-default&lt;/code>, and &lt;code class="verbatim">--spacing-large-mobile&lt;/code>.&lt;/p>
&lt;/div>
&lt;/div>
&lt;div id="outline-container-headline-7" class="outline-4">
&lt;h4 id="headline-7">
Theme Switching
&lt;/h4>
&lt;div id="outline-text-headline-7" class="outline-text-4">
&lt;p>
The library provides a hook for easy theme switching:&lt;/p>
&lt;div class="src src-javascript">
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="kd">function&lt;/span> &lt;span class="nx">ThemeToggle&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">theme&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">toggle&lt;/span> &lt;span class="p">}&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">useCssVarsDesignTokenContext&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">&amp;lt;&lt;/span>&lt;span class="nx">button&lt;/span> &lt;span class="nx">onClick&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="nx">toggle&lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">Current&lt;/span> &lt;span class="nx">theme&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="nx">theme&lt;/span>&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">&amp;lt;&lt;/span>&lt;span class="err">/button&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/div>
&lt;/div>
&lt;/div>
&lt;/div>
&lt;/div>
&lt;/div>
&lt;/div>
&lt;div id="outline-container-headline-8" class="outline-2">
&lt;h2 id="headline-8">
Real-World Applications
&lt;/h2>
&lt;div id="outline-text-headline-8" class="outline-text-2">
&lt;div id="outline-container-headline-9" class="outline-3">
&lt;h3 id="headline-9">
Responsive Design
&lt;/h3>
&lt;div id="outline-text-headline-9" class="outline-text-3">
&lt;p>
CSS variables work seamlessly with media queries:&lt;/p>
&lt;div class="src src-css">
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-css" data-lang="css">&lt;span class="line">&lt;span class="cl">&lt;span class="p">:&lt;/span>&lt;span class="nd">root&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nv">--sidebar-width&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="nf">var&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">--&lt;/span>&lt;span class="n">layout&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">sidebar&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="kc">default&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">@&lt;/span>&lt;span class="k">media&lt;/span> &lt;span class="o">(&lt;/span>&lt;span class="nt">max-width&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="nt">768px&lt;/span>&lt;span class="o">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">:&lt;/span>&lt;span class="nd">root&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nv">--sidebar-width&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="nf">var&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">--&lt;/span>&lt;span class="n">layout&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">sidebar&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="kc">compact&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/div>
&lt;/div>
&lt;/div>
&lt;div id="outline-container-headline-10" class="outline-3">
&lt;h3 id="headline-10">
Component Libraries
&lt;/h3>
&lt;div id="outline-text-headline-10" class="outline-text-3">
&lt;p>
Design tokens can help create consistent component libraries:&lt;/p>
&lt;div class="src src-javascript">
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="kd">function&lt;/span> &lt;span class="nx">Button&lt;/span>&lt;span class="p">({&lt;/span> &lt;span class="nx">variant&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s1">&amp;#39;primary&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">children&lt;/span> &lt;span class="p">})&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">&amp;lt;&lt;/span>&lt;span class="nx">button&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">style&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">{{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">backgroundColor&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="sb">`var(--color-&lt;/span>&lt;span class="si">${&lt;/span>&lt;span class="nx">variant&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="sb">)`&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">padding&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;var(--spacing-medium)&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">borderRadius&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;var(--border-radius-medium)&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>&lt;span class="nx">children&lt;/span>&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">&amp;lt;&lt;/span>&lt;span class="err">/button&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/div>
&lt;p>
You even have access to the current token values themselves, if needed:&lt;/p>
&lt;div class="src src-javascript">
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="kd">function&lt;/span> &lt;span class="p">({&lt;/span> &lt;span class="nx">children&lt;/span> &lt;span class="p">})&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">token&lt;/span> &lt;span class="p">}&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">useCssVarsDesignTokenContext&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">newColor&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">desaturate&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">token&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">color&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">backgroundColor&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">&amp;lt;&lt;/span>&lt;span class="nx">div&lt;/span> &lt;span class="nx">style&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">{{&lt;/span> &lt;span class="nx">backgroundColor&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="nx">newColor&lt;/span> &lt;span class="p">}}&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>&lt;span class="nx">children&lt;/span>&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">&amp;lt;&lt;/span>&lt;span class="err">/div&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/div>
&lt;/div>
&lt;/div>
&lt;/div>
&lt;/div>
&lt;div id="outline-container-headline-11" class="outline-2">
&lt;h2 id="headline-11">
Benefits Over Alternative Approaches
&lt;/h2>
&lt;div id="outline-text-headline-11" class="outline-text-2">
&lt;ol>
&lt;li>&lt;strong>Simplicity&lt;/strong>: No build tools or preprocessors required&lt;/li>
&lt;li>&lt;strong>Performance&lt;/strong>: CSS variables are highly optimized in modern browsers&lt;/li>
&lt;li>&lt;strong>Developer Experience&lt;/strong>: Easy to debug using browser dev tools&lt;/li>
&lt;li>&lt;strong>Framework Agnostic&lt;/strong>: The underlying CSS variables work everywhere&lt;/li>
&lt;li>&lt;strong>Progressive Enhancement&lt;/strong>: Falls back gracefully if JavaScript fails&lt;/li>
&lt;/ol>
&lt;/div>
&lt;/div>
&lt;div id="outline-container-headline-12" class="outline-2">
&lt;h2 id="headline-12">
Getting Started
&lt;/h2>
&lt;div id="outline-text-headline-12" class="outline-text-2">
&lt;p>
Install the package:&lt;/p>
&lt;div class="src src-sh">
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-sh" data-lang="sh">&lt;span class="line">&lt;span class="cl">npm install css-vars-design-token&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/div>
&lt;p>
The library weighs less than 1KB gzipped and has zero dependencies beyond React.&lt;/p>
&lt;p>
Check out the &lt;a href="https://github.com/khtdr/css-vars-design-token">GitHub repository&lt;/a> for more examples and documentation.&lt;/p>
&lt;/div>
&lt;/div>
&lt;div id="outline-container-headline-13" class="outline-2">
&lt;h2 id="headline-13">
Additional Links
&lt;/h2>
&lt;div id="outline-text-headline-13" class="outline-text-2">
&lt;ul>
&lt;li>&lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties">https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://en.wikipedia.org/wiki/Design_system">https://en.wikipedia.org/wiki/Design_system&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://react.dev/reference/react/createContext#provider">https://react.dev/reference/react/createContext#provider&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.npmjs.com/package/css-vars-design-token">https://www.npmjs.com/package/css-vars-design-token&lt;/a>&lt;/li>
&lt;/ul>
&lt;/div>
&lt;/div>
]]></content:encoded></item><item><title>opts.js</title><description> opts.js is a Javascript helper library for command-line applications, for accepting and parsing command-line arguments, flags and options, and automatically generating a useful help message.
Introduction to Opts.js Why choose opts.js over something bigger and better?
Small : Under 10kb, uncompressed. Stable : Relatively unchanged since 2010. See changelog. Standalone : No package manager necessary, no compiling needed. See src/opts.js. Tested : Millions of downloads per year. See npm/opts. Quick-Start example The following example set up a custom "version" function, and opts in to the automatic help message. No pun intended.</description><link>https://khtdr.com/opts/</link><guid>https://khtdr.com/opts/</guid><pubDate>Fri, 02 Aug 2019 00:00:00 +0000</pubDate><category>Software</category><content:encoded>
&lt;![CDATA[
&lt;p>
&lt;code class="verbatim">opts.js&lt;/code> is a Javascript helper library for command-line applications, for accepting and parsing command-line arguments, flags and options, and automatically generating a useful help message.&lt;/p>
&lt;div id="outline-container-intro" class="outline-2">
&lt;h2 id="intro">
Introduction to Opts.js
&lt;/h2>
&lt;div id="outline-text-intro" class="outline-text-2">
&lt;p>
Why choose &lt;code class="verbatim">opts.js&lt;/code> over something bigger and better?&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Small :&lt;/strong> Under 10kb, &lt;em>uncompressed&lt;/em>.&lt;/li>
&lt;li>&lt;strong>Stable :&lt;/strong> Relatively unchanged since 2010. See &lt;a href="https://github.com/khtdr/opts/blob/master/CHANGES.org">changelog&lt;/a>.&lt;/li>
&lt;li>&lt;strong>Standalone :&lt;/strong> No package manager necessary, no compiling needed. See &lt;a href="https://raw.githubusercontent.com/khtdr/opts/master/src/opts.js">src/opts.js&lt;/a>.&lt;/li>
&lt;li>&lt;strong>Tested :&lt;/strong> &lt;em>Millions&lt;/em> of downloads per year. See &lt;a href="https://www.npmjs.com/package/opts">npm/opts&lt;/a>.&lt;/li>
&lt;/ul>
&lt;div id="outline-container-example-1" class="outline-3">
&lt;h3 id="example-1">
Quick-Start example
&lt;/h3>
&lt;div id="outline-text-example-1" class="outline-text-3">
&lt;p>
The following example set up a custom &amp;#34;version&amp;#34; function, and opts in to the automatic help message. No pun intended.&lt;/p>
&lt;p>
&lt;a href="https://raw.githubusercontent.com/khtdr/opts/master/examples/example1.js">opts/examples/example1.js&lt;/a>&lt;/p>
&lt;div class="src src-javascript">
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="kd">var&lt;/span> &lt;span class="nx">opts&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">require&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;opts&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">var&lt;/span> &lt;span class="nx">options&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span> &lt;span class="kr">short&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;v&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">,&lt;/span> &lt;span class="kr">long&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;version&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">,&lt;/span> &lt;span class="nx">description&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;Show version and exit&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">,&lt;/span> &lt;span class="nx">callback&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="kd">function&lt;/span> &lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;v1.0&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="nx">process&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">exit&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">];&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">opts&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">parse&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">options&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;Example 1&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">process&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">exit&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">);&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/div>
&lt;div class="src src-bash">
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">node ./example1&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/div>
&lt;pre class="example">
Example 1
&lt;/pre>
&lt;div class="src src-bash">
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">node ./example1 --help&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/div>
&lt;pre class="example">
Usage: node ./example1 [options]
Show this help message
--help
Show version and exit
-v, --version
&lt;/pre>
&lt;div class="src src-sh">
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-sh" data-lang="sh">&lt;span class="line">&lt;span class="cl">node ./example1 -v&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/div>
&lt;pre class="example">
v1.0
&lt;/pre>
&lt;div class="center-block" style="text-align: center; margin-left: auto; margin-right: auto;">
&lt;p>See &lt;a href="#more-examples">more examples&lt;/a> below.&lt;/p>
&lt;/div>
&lt;/div>
&lt;/div>
&lt;/div>
&lt;/div>
&lt;div id="outline-container-setup" class="outline-2">
&lt;h2 id="setup">
Installation
&lt;/h2>
&lt;div id="outline-text-setup" class="outline-text-2">
&lt;div id="outline-container-standalone" class="outline-3">
&lt;h3 id="standalone">
No NPM dependencies are required
&lt;/h3>
&lt;div id="outline-text-standalone" class="outline-text-3">
&lt;p>
To use &lt;a href="https://raw.githubusercontent.com/khtdr/opts/master/src/opts.js">opts.js&lt;/a>, you &lt;em>do not&lt;/em> need to use NPM or any package manager. It is written in plain-old Javascript, and can be downloaded and included in your Node.js project as-is. All of &lt;a href="https://github.com/khtdr/opts/tree/master/examples">the examples&lt;/a> use this approach.&lt;/p>
&lt;div class="src src-bash">
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">cd&lt;/span> /path/to/your/project
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">curl -o opts.js https://raw.githubusercontent.com/khtdr/opts/master/src/opts.js&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/div>
&lt;/div>
&lt;/div>
&lt;div id="outline-container-npm" class="outline-3">
&lt;h3 id="npm">
Typescript and NPM packages for convenience
&lt;/h3>
&lt;div id="outline-text-npm" class="outline-text-3">
&lt;p>
If you are using NPM in your project, you can install it using the name &lt;code class="verbatim">opts&lt;/code>.&lt;/p>
&lt;div class="src src-bash">
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">npm install opts&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/div>
&lt;/div>
&lt;/div>
&lt;/div>
&lt;/div>
&lt;div id="outline-container-quickstart" class="outline-2">
&lt;h2 id="quickstart">
Basic usage and setup
&lt;/h2>
&lt;div id="outline-text-quickstart" class="outline-text-2">
&lt;p>
To use, import the library and call &lt;code class="verbatim">opts.parse&lt;/code> with your configurations. The various types of configurations are covered further down.&lt;/p>
&lt;div class="src src-javascript">
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="kd">var&lt;/span> &lt;span class="nx">opts&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">require&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;opts&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">opts&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">parse&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">options&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">arguments&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">help&lt;/span>&lt;span class="p">);&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/div>
&lt;div class="center-block" style="text-align: center; margin-left: auto; margin-right: auto;">
&lt;p>&lt;em>or with the more modern syntax&lt;/em>&lt;/p>
&lt;/div>
&lt;div class="src src-javascript">
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="kr">import&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="nx">as&lt;/span> &lt;span class="nx">opts&lt;/span> &lt;span class="nx">from&lt;/span> &lt;span class="s1">&amp;#39;opts&amp;#39;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">opts&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">parse&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">options&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">arguments&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">help&lt;/span>&lt;span class="p">);&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/div>
&lt;p>
If you installed &lt;code class="verbatim">opts&lt;/code> with NPM, the typescript definitions should automatically be available in your editor. Otherwise you can download the &lt;a href="https://raw.githubusercontent.com/khtdr/opts/master/src/opts.d.ts">definition (.d.ts) file here&lt;/a>.&lt;/p>
&lt;/div>
&lt;/div>
&lt;div id="outline-container-api" class="outline-2">
&lt;h2 id="api">
API configurations
&lt;/h2>
&lt;div id="outline-text-api" class="outline-text-2">
&lt;p>
&lt;code class="verbatim">opts.parse(options, arguments, help)&lt;/code>&lt;/p>
&lt;p>
Options are flag-arguments. Arguments are everything else. Consider the following hypothetical command for starting a server that listens on &lt;a href="http://0.0.0.0:4000">http://0.0.0.0:4000&lt;/a>&lt;/p>
&lt;div class="src src-bash">
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">node ./my-app start --host 0.0.0.0 -p &lt;span class="m">4000&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/div>
&lt;p>
In this example, the options are &lt;code class="verbatim">--host 0.0.0.0&lt;/code> and &lt;code class="verbatim">-p 4000&lt;/code>. The argument is &lt;code class="verbatim">start&lt;/code>. The arguments can be after, before, or among the options.&lt;/p>
&lt;div id="outline-container-api-options" class="outline-3">
&lt;h3 id="api-options">
Options
&lt;/h3>
&lt;div id="outline-text-api-options" class="outline-text-3">
&lt;p>
&lt;code>options&lt;/code> is an array of option objects. Each option in the array can have the following fields. None are required, but you should at least provide a short or long name.&lt;/p>
&lt;div class="src src-javascript">
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="kd">let&lt;/span> &lt;span class="nx">options&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span> &lt;span class="kr">short&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;l&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">long&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;list&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">description&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;Show a list&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">value&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="kc">false&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1">// default false
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">required&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1">// default false
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">callback&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="kd">function&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">value&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="p">...&lt;/span> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span> &lt;span class="c1">// ... followed by more options
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="p">];&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/div>
&lt;/div>
&lt;/div>
&lt;div id="outline-container-api-arguments" class="outline-3">
&lt;h3 id="api-arguments">
Arguments
&lt;/h3>
&lt;div id="outline-text-api-arguments" class="outline-text-3">
&lt;p>
&lt;code>arguments&lt;/code> require less configuration. This is an optional argument to &lt;code class="verbatim">opts.parse&lt;/code>:&lt;/p>
&lt;div class="src src-javascript">
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="kd">let&lt;/span> &lt;span class="nx">arguments&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span> &lt;span class="nx">name&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;script&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">required&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1">// not required by default
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">callback&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="kd">function&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">value&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="p">...&lt;/span> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">];&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/div>
&lt;/div>
&lt;/div>
&lt;div id="outline-container-api-help" class="outline-3">
&lt;h3 id="api-help">
Help auto-generator
&lt;/h3>
&lt;div id="outline-text-api-help" class="outline-text-3">
&lt;p>
Finally, you can add an automatically generated help message by passing
a last parameter of &lt;code class="verbatim">true&lt;/code>. This is also an optional argument to &lt;code class="verbatim">opts.parse&lt;/code>.&lt;/p>
&lt;div class="src src-javascript">
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">opts&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">parse&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">options&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// or if you want more control, you can do:
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="cm">/*
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> options.push({
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> long : &amp;#39;help&amp;#39;,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> description : &amp;#39;Show this help message&amp;#39;,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> callback : require(&amp;#39;opts&amp;#39;).help,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> }
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> opts.parse(options);
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm">*/&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/div>
&lt;/div>
&lt;/div>
&lt;/div>
&lt;/div>
&lt;div id="outline-container-more-examples" class="outline-2">
&lt;h2 id="more-examples">
More examples
&lt;/h2>
&lt;div id="outline-text-more-examples" class="outline-text-2">
&lt;div id="outline-container-example-2" class="outline-3">
&lt;h3 id="example-2">
Showcase of features and options
&lt;/h3>
&lt;div id="outline-text-example-2" class="outline-text-3">
&lt;p>
&lt;a href="https://raw.githubusercontent.com/khtdr/opts/master/examples/example2.js">opts/examples/example2.js&lt;/a>&lt;/p>
&lt;div class="src src-javascript">
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="cm">/**
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> * More complex example.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> *
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> * Run:
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> * node example2.js --help
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> * and play with the options to see the behavior.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> *
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> * This example shows different ways of using the library. It is deliberately
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> * inconsistent. Choose the style that suits you best.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> */&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">var&lt;/span> &lt;span class="nx">opts&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">require&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;opts&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">,&lt;/span> &lt;span class="nx">host&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s1">&amp;#39;localhost&amp;#39;&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">// default host value
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">var&lt;/span> &lt;span class="nx">options&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span> &lt;span class="kr">short&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;v&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">,&lt;/span> &lt;span class="kr">long&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;version&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">,&lt;/span> &lt;span class="nx">description&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;Show version and exit&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">,&lt;/span> &lt;span class="nx">callback&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="kd">function&lt;/span> &lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;v1.0&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="nx">process&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">exit&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span> &lt;span class="kr">short&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;l&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">,&lt;/span> &lt;span class="kr">long&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;list&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">,&lt;/span> &lt;span class="nx">description&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;List all files&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span> &lt;span class="kr">short&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;f&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">,&lt;/span> &lt;span class="kr">long&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;file&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">,&lt;/span> &lt;span class="nx">description&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;Load a file&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">,&lt;/span> &lt;span class="nx">value&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="kc">true&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">,&lt;/span> &lt;span class="nx">required&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="kc">true&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span> &lt;span class="kr">short&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;d&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">,&lt;/span> &lt;span class="kr">long&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;debug&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">,&lt;/span> &lt;span class="nx">description&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;Set a debug level&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">,&lt;/span> &lt;span class="nx">value&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="kc">true&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span> &lt;span class="kr">short&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;h&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">,&lt;/span> &lt;span class="kr">long&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;host&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">,&lt;/span> &lt;span class="nx">description&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;The hostname to connect to&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">,&lt;/span> &lt;span class="nx">value&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="kc">true&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">,&lt;/span> &lt;span class="nx">callback&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="kd">function&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">value&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">host&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">value&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">}&lt;/span> &lt;span class="c1">// override host value
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span> &lt;span class="kr">short&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;p&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">,&lt;/span> &lt;span class="kr">long&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;port&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">,&lt;/span> &lt;span class="nx">description&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;The port to connect to&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">,&lt;/span> &lt;span class="nx">value&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="kc">true&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">];&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">opts&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">parse&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">options&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">var&lt;/span> &lt;span class="nx">port&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">opts&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;port&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">||&lt;/span> &lt;span class="mi">8000&lt;/span> &lt;span class="c1">// default port value
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="p">,&lt;/span> &lt;span class="nx">debug&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">opts&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;d&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">||&lt;/span> &lt;span class="s1">&amp;#39;info&amp;#39;&lt;/span> &lt;span class="c1">// default debug value
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="p">,&lt;/span> &lt;span class="nx">file&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">opts&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;f&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">,&lt;/span> &lt;span class="nx">list&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">opts&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;list&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">var&lt;/span> &lt;span class="nx">arg1&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">opts&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">args&lt;/span>&lt;span class="p">()[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">,&lt;/span> &lt;span class="nx">arg2&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">opts&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">args&lt;/span>&lt;span class="p">()[&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">];&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">list&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;List arg was set&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">file&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;File arg was set: &amp;#39;&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nx">file&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;Debug level is: &amp;#39;&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nx">debug&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;Host is: &amp;#39;&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nx">host&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;Port is: &amp;#39;&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nx">port&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">arg1&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;Extra arg 1: &amp;#39;&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nx">arg1&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">arg2&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;Extra arg 2: &amp;#39;&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nx">arg2&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">process&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">exit&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">);&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/div>
&lt;/div>
&lt;/div>
&lt;div id="outline-container-example-3" class="outline-3">
&lt;h3 id="example-3">
Conflict detection
&lt;/h3>
&lt;div id="outline-text-example-3" class="outline-text-3">
&lt;p>
&lt;a href="https://raw.githubusercontent.com/khtdr/opts/master/examples/example3.js">opts/examples/example3.js&lt;/a>&lt;/p>
&lt;div class="src src-javascript">
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="cm">/**
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> * Simple example that is broken by design (conflicting options)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> *
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> * Examples:
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> * $ node example3.js
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> * &amp;gt; Conflicting flags: -v
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> */&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">var&lt;/span> &lt;span class="nx">opts&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">require&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;opts&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">var&lt;/span> &lt;span class="nx">options&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span> &lt;span class="kr">short&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;v&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">,&lt;/span> &lt;span class="nx">description&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;Show version and exit&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span> &lt;span class="kr">short&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;v&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">,&lt;/span> &lt;span class="nx">description&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;Be verbose&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">];&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">opts&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">parse&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">options&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;Example 3&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">process&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">exit&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">);&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/div>
&lt;/div>
&lt;/div>
&lt;div id="outline-container-example-4" class="outline-3">
&lt;h3 id="example-4">
Using named arguments and from within a library
&lt;/h3>
&lt;div id="outline-text-example-4" class="outline-text-3">
&lt;p>
&lt;a href="https://raw.githubusercontent.com/khtdr/opts/master/examples/example4.js">opts/examples/example4.js&lt;/a>&lt;/p>
&lt;div class="src src-javascript">
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="cm">/**
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> * Advanced example using namespaces for a library and named arguments
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> *
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> * Run:
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> * node example4.js --help
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> * and play with the options to see the behavior.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cm"> */&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">var&lt;/span> &lt;span class="nx">opts&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">require&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;opts&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">,&lt;/span> &lt;span class="nx">host&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s1">&amp;#39;localhost&amp;#39;&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="c1">// default host value
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// Example of using some library in the same app
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="kd">var&lt;/span> &lt;span class="nx">libOpts&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span> &lt;span class="kr">short&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;l&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">,&lt;/span> &lt;span class="kr">long&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;list&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">,&lt;/span> &lt;span class="nx">description&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;Show the library list&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">,&lt;/span> &lt;span class="nx">callback&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="kd">function&lt;/span> &lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;mylib list!&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">];&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">opts&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">libOpts&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;mylib&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">var&lt;/span> &lt;span class="nx">options&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span> &lt;span class="kr">short&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;l&amp;#39;&lt;/span> &lt;span class="c1">// deliberately conflicting with &amp;#39;mylib&amp;#39; option
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="p">,&lt;/span> &lt;span class="kr">long&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;list&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">,&lt;/span> &lt;span class="nx">description&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;List all files&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span> &lt;span class="kr">short&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;d&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">,&lt;/span> &lt;span class="kr">long&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;debug&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">,&lt;/span> &lt;span class="nx">description&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;Set a debug level&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">,&lt;/span> &lt;span class="nx">value&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="kc">true&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">];&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">var&lt;/span> &lt;span class="nx">arguments&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">name&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;script&amp;#39;&lt;/span> &lt;span class="p">,&lt;/span> &lt;span class="nx">required&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="kc">true&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">,&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">name&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;timeout&amp;#39;&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">];&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">opts&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">parse&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">options&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">arguments&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">var&lt;/span> &lt;span class="nx">debug&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">opts&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;d&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">||&lt;/span> &lt;span class="s1">&amp;#39;info&amp;#39;&lt;/span> &lt;span class="c1">// default debug value
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="p">,&lt;/span> &lt;span class="nx">list&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">opts&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;list&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">var&lt;/span> &lt;span class="nx">script&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">opts&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">arg&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;script&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">,&lt;/span> &lt;span class="nx">timeout&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">opts&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">arg&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;timeout&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">||&lt;/span> &lt;span class="mi">30&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">list&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;List arg was set&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;Debug level is: &amp;#39;&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nx">debug&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;Script is: &amp;#39;&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nx">script&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;Timeout is: &amp;#39;&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nx">timeout&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">process&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">exit&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">);&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/div>
&lt;blockquote>
&lt;p>You can find the source code and all examples at Github, &lt;a href="https://github.com/khtdr/opts">github.com/khtdr/opts&lt;/a>.&lt;/p>
&lt;/blockquote>
&lt;/div>
&lt;/div>
&lt;/div>
&lt;/div>
]]></content:encoded></item><item><title>Resume</title><description> Resume for Jose Mazzarelli Summary With 20+ years of experience building reliable software across various industries, I am skilled in full-stack development and team leadership focusing on secure web application development.
Contact Information Email Github LinkedIn NPM Packages Professional Experience Private Consulting 2024 - Present AI Consultant
Part of a small team providing AI consulting and services.
Postgres Typescript LLM RAG Vector Search
Financial document store and semantic search with LLM answer completion. Typescript React Chat App Document Viewing Chat app for interacting with backend RAG API. – -</description><link>https://khtdr.com/resume/</link><guid>https://khtdr.com/resume/</guid><pubDate>Fri, 02 Aug 2019 00:00:00 +0000</pubDate><content:encoded>
&lt;![CDATA[
&lt;div id="outline-container-headline-1" class="outline-2">
&lt;h2 id="headline-1">
Resume for Jose Mazzarelli
&lt;/h2>
&lt;div id="outline-text-headline-1" class="outline-text-2">
&lt;div id="outline-container-headline-2" class="outline-3">
&lt;h3 id="headline-2">
Summary
&lt;/h3>
&lt;div id="outline-text-headline-2" class="outline-text-3">
&lt;p>With 20+ years of experience building reliable software across various industries, I am skilled in full-stack development and team leadership focusing on secure web application development.&lt;/p>
&lt;/div>
&lt;/div>
&lt;div id="outline-container-headline-3" class="outline-3">
&lt;h3 id="headline-3">
Contact Information
&lt;/h3>
&lt;div id="outline-text-headline-3" class="outline-text-3">
&lt;ul>
&lt;li>&lt;a href="mailto:mazzarelli+resume@gmail.com">Email&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://github.com/khtdr">Github&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.linkedin.com/in/joey-mazzarelli-7522a727/">LinkedIn&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.npmjs.com/~mazzarelli">NPM Packages&lt;/a>&lt;/li>
&lt;/ul>
&lt;/div>
&lt;/div>
&lt;/div>
&lt;/div>
&lt;div id="outline-container-headline-4" class="outline-2">
&lt;h2 id="headline-4">
Professional Experience
&lt;/h2>
&lt;div id="outline-text-headline-4" class="outline-text-2">
&lt;div id="outline-container-headline-5" class="outline-3">
&lt;h3 id="headline-5">
Private Consulting &lt;code class="verbatim">2024 - Present&lt;/code>
&lt;/h3>
&lt;div id="outline-text-headline-5" class="outline-text-3">
&lt;p>&lt;code>AI Consultant&lt;/code>&lt;/p>
&lt;p>
Part of a small team providing AI consulting and services.&lt;/p>
&lt;ul>
&lt;li>&lt;code class="verbatim">Postgres&lt;/code> &lt;code class="verbatim">Typescript&lt;/code> &lt;code class="verbatim">LLM&lt;/code> &lt;code class="verbatim">RAG&lt;/code> &lt;code class="verbatim">Vector Search&lt;/code>&lt;br>
Financial document store and semantic search with LLM answer completion.&lt;/li>
&lt;li>&lt;code class="verbatim">Typescript&lt;/code> &lt;code class="verbatim">React&lt;/code> &lt;code class="verbatim">Chat App&lt;/code> &lt;code class="verbatim">Document Viewing&lt;/code> &lt;br>
Chat app for interacting with backend RAG API.&lt;/li>
&lt;/ul>
&lt;p>– -&lt;/p>
&lt;/div>
&lt;/div>
&lt;div id="outline-container-headline-6" class="outline-3">
&lt;h3 id="headline-6">
VZBL &lt;code class="verbatim">2023 - Present&lt;/code>
&lt;/h3>
&lt;div id="outline-text-headline-6" class="outline-text-3">
&lt;p>&lt;code>Co-founder&lt;/code> &lt;code>Lead Developer&lt;/code>&lt;/p>
&lt;ul>
&lt;li>Leads the application development, focusing on application architecture and data exploration.&lt;/li>
&lt;li>Designs and builds key features including onboarding flows, dashboards, and data visualizations.&lt;/li>
&lt;li>Built features including user management, multi-tenant security, and customizable interfaces.&lt;/li>
&lt;/ul>
&lt;p>– -&lt;/p>
&lt;/div>
&lt;/div>
&lt;div id="outline-container-headline-7" class="outline-3">
&lt;h3 id="headline-7">
SocialChorus/FirstUp &lt;code class="verbatim">2018 - 2023&lt;/code>
&lt;/h3>
&lt;div id="outline-text-headline-7" class="outline-text-3">
&lt;p>&lt;code>Senior Software Engineer&lt;/code> &lt;code>Team Lead&lt;/code>&lt;br>
&lt;code class="verbatim">Typescript&lt;/code> &lt;code class="verbatim">Ruby&lt;/code> &lt;code class="verbatim">Rails&lt;/code> &lt;code class="verbatim">React&lt;/code> &lt;code class="verbatim">Redux&lt;/code> &lt;code class="verbatim">Node.js&lt;/code> &lt;code class="verbatim">Redis&lt;/code> &lt;code class="verbatim">Postgres&lt;/code> &lt;code class="verbatim">Puppeteer&lt;/code> &lt;code class="verbatim">NPM&lt;/code> &lt;code class="verbatim">MJML&lt;/code> &lt;code class="verbatim">Cypress&lt;/code> &lt;code class="verbatim">RSpec&lt;/code>&lt;/p>
&lt;ul>
&lt;li>Interviewed several hundred candidates as part of the core hiring team.&lt;/li>
&lt;li>Managed teams in publishing and analytics/reporting in Agile and Kanban processes.&lt;/li>
&lt;li>Led the transition to modern front-end tools, improving app performance and user experience.&lt;/li>
&lt;li>Designed and built custom publishing tools used to create content for millions of users.&lt;/li>
&lt;li>Integrated Metabase and Tableau into the product for analytics and reporting.&lt;/li>
&lt;/ul>
&lt;p>– -&lt;/p>
&lt;/div>
&lt;/div>
&lt;div id="outline-container-headline-8" class="outline-3">
&lt;h3 id="headline-8">
Kount &lt;code class="verbatim">2007 - 2018&lt;/code>
&lt;/h3>
&lt;div id="outline-text-headline-8" class="outline-text-3">
&lt;p>&lt;code>Software Engineer&lt;/code> &lt;code>UX Architect&lt;/code> &lt;code>Software Architect&lt;/code>&lt;br>
&lt;code class="verbatim">jQuery&lt;/code> &lt;code class="verbatim">Javascript&lt;/code> &lt;code class="verbatim">CoffeeScript&lt;/code> &lt;code class="verbatim">PHP&lt;/code> &lt;code class="verbatim">Oracle (PLSQL)&lt;/code> &lt;code class="verbatim">React&lt;/code> &lt;code class="verbatim">Redux&lt;/code> &lt;code class="verbatim">Node.js&lt;/code> &lt;code class="verbatim">OWASP&lt;/code> &lt;code class="verbatim">JWT&lt;/code> &lt;code class="verbatim">PHPUnit&lt;/code>&lt;/p>
&lt;ul>
&lt;li>One of the original engineers at Kount, contributing to its growth and eventual acquisition by Equifax.&lt;/li>
&lt;li>Focused on speed and security, working on authentication, dependency injection, and theming frameworks.&lt;/li>
&lt;li>Responsible for software security training and best practice implementations.&lt;/li>
&lt;li>Developed various customer facing and internal tools.&lt;/li>
&lt;/ul>
&lt;p>– -&lt;/p>
&lt;/div>
&lt;/div>
&lt;div id="outline-container-headline-9" class="outline-3">
&lt;h3 id="headline-9">
Boise State University &lt;code class="verbatim">2014 - 2018&lt;/code>
&lt;/h3>
&lt;div id="outline-text-headline-9" class="outline-text-3">
&lt;p>&lt;code>Adjunct Lecturer&lt;/code>&lt;/p>
&lt;ul>
&lt;li>Taught &lt;em>Intro to Web Development&lt;/em> course.&lt;/li>
&lt;li>Taught &lt;em>Programming Languages&lt;/em> course.&lt;/li>
&lt;/ul>
&lt;p>– -&lt;/p>
&lt;/div>
&lt;/div>
&lt;div id="outline-container-headline-10" class="outline-3">
&lt;h3 id="headline-10">
YourList &lt;code class="verbatim">2011&lt;/code>
&lt;/h3>
&lt;div id="outline-text-headline-10" class="outline-text-3">
&lt;p>&lt;code>Lead Developer&lt;/code> &lt;code>Software Architect&lt;/code>&lt;/p>
&lt;ul>
&lt;li>&lt;code class="verbatim">Python&lt;/code> &lt;code class="verbatim">MySQL&lt;/code> &lt;code class="verbatim">MQ&lt;/code>&lt;br>
Developed a distributed scraping algorithm.&lt;/li>
&lt;li>&lt;code class="verbatim">Javascript&lt;/code> &lt;code class="verbatim">jQuery&lt;/code> &lt;code class="verbatim">PHP&lt;/code> &lt;code class="verbatim">MySQL&lt;/code> &lt;br>
Clone of popular sell-it-yourself website.&lt;/li>
&lt;/ul>
&lt;p>– -&lt;/p>
&lt;/div>
&lt;/div>
&lt;div id="outline-container-headline-11" class="outline-3">
&lt;h3 id="headline-11">
Keynetics &lt;code class="verbatim">2006 - 2007&lt;/code>
&lt;/h3>
&lt;div id="outline-text-headline-11" class="outline-text-3">
&lt;p>&lt;code>Full Stack Developer&lt;/code>&lt;/p>
&lt;ul>
&lt;li>&lt;code class="verbatim">Javascript&lt;/code> &lt;code class="verbatim">jQuery&lt;/code> &lt;code class="verbatim">PHP&lt;/code> &lt;code class="verbatim">Perl&lt;/code> &lt;code class="verbatim">Python&lt;/code>&lt;br>
Worked on financial processing code and prototyped security tools.&lt;/li>
&lt;/ul>
&lt;p>– -&lt;/p>
&lt;/div>
&lt;/div>
&lt;div id="outline-container-headline-12" class="outline-3">
&lt;h3 id="headline-12">
PersonalShopper &lt;code class="verbatim">2005 - 2006&lt;/code>
&lt;/h3>
&lt;div id="outline-text-headline-12" class="outline-text-3">
&lt;p>&lt;code>Full Stack Developer)&lt;/code>&lt;/p>
&lt;ul>
&lt;li>&lt;code class="verbatim">Javascript&lt;/code> &lt;code class="verbatim">jQuery&lt;/code> &lt;code class="verbatim">Java&lt;/code> &lt;code class="verbatim">Oracle&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>– -&lt;/p>
&lt;/div>
&lt;/div>
&lt;div id="outline-container-headline-13" class="outline-3">
&lt;h3 id="headline-13">
Idaho Transportation Department &lt;code class="verbatim">2002 - 2004&lt;/code>
&lt;/h3>
&lt;div id="outline-text-headline-13" class="outline-text-3">
&lt;p>&lt;code>Intern&lt;/code> &lt;code>Web Developer&lt;/code>&lt;/p>
&lt;ul>
&lt;li>&lt;code class="verbatim">Javascript&lt;/code> &lt;code class="verbatim">ASP.NET&lt;/code> &lt;code class="verbatim">MS SQL&lt;/code>&lt;br>
Worked with many departments to develop intranet and website applications. &lt;br>
&lt;a href="https://apps.itd.idaho.gov/apps/mediamanagermvc/transporter/2004/100104_Trans/100104_ITDwebsite.html">Project News Announcement&lt;/a>&lt;/li>
&lt;/ul>
&lt;/div>
&lt;/div>
&lt;/div>
&lt;/div>
&lt;div id="outline-container-headline-14" class="outline-2">
&lt;h2 id="headline-14">
Education
&lt;/h2>
&lt;div id="outline-text-headline-14" class="outline-text-2">
&lt;p>BS Computer Science Boise State University 2004&lt;/p>
&lt;/div>
&lt;/div>
]]></content:encoded></item><item><title>A Developer's Design Implementation Checklist</title><description> Mockups never tell the whole story After nearly 25 years of leading UI/UX development, I've learned that the difference between a successful project and a death march often comes down to one thing: understanding the full scope of work - especially the parts that aren't in the mockups.
I love working with designers. Their creativity and vision are essential to creating great products. But even the most talented designers don't always think in terms of application state and edge cases. That's where we developers come in.</description><link>https://khtdr.com/design-implementation-checklist.html</link><guid>https://khtdr.com/design-implementation-checklist.html</guid><pubDate>Fri, 24 Jan 2025 00:00:00 +0000</pubDate><category>Tutorials</category><content:encoded>
&lt;![CDATA[
&lt;div id="outline-container-headline-1" class="outline-2">
&lt;h2 id="headline-1">
Mockups never tell the whole story
&lt;/h2>
&lt;div id="outline-text-headline-1" class="outline-text-2">
&lt;p>
After nearly 25 years of leading UI/UX development, I&amp;#39;ve learned that the difference between a successful project and a death march often comes down to one thing: understanding the full scope of work - especially the parts that aren&amp;#39;t in the mockups.&lt;/p>
&lt;p>
I love working with designers. Their creativity and vision are essential to creating great products. But even the most talented designers don&amp;#39;t always think in terms of application state and edge cases. That&amp;#39;s where we developers come in.&lt;/p>
&lt;p>
&lt;div style="text-align: center">
&lt;div style="background-color: var(--well-color); border-bottom: solid 1px var(--background-color); padding: 16px; max-width: 570px; margin: auto">
&lt;div style="max-width: 440px; color: var(--accent-color); transform: rotate(5deg); margin: auto" class="goat svg-container">
&lt;svg xmlns="http://www.w3.org/2000/svg"
font-family="Menlo, Lucida Console,monospace"
viewBox="0 0 344 153">
&lt;g transform='translate(8,16)'>
&lt;path d='M 96,16 L 136,16' fill='none' stroke='currentColor'>&lt;/path>
&lt;path d='M 192,16 L 232,16' fill='none' stroke='currentColor'>&lt;/path>
&lt;path d='M 56,48 L 56,112' fill='none' stroke='currentColor'>&lt;/path>
&lt;path d='M 160,48 L 160,112' fill='none' stroke='currentColor'>&lt;/path>
&lt;path d='M 272,40 L 272,56' fill='none' stroke='currentColor'>&lt;/path>
&lt;polygon points='144.000000,16.000000 132.000000,10.400000 132.000000,21.600000' fill='currentColor' transform='rotate(0.000000, 136.000000, 16.000000)'>&lt;/polygon>
&lt;polygon points='240.000000,16.000000 228.000000,10.400000 228.000000,21.600000' fill='currentColor' transform='rotate(0.000000, 232.000000, 16.000000)'>&lt;/polygon>
&lt;text text-anchor='middle' x='40' y='20' fill='currentColor' style='font-size:1em'>M&lt;/text>
&lt;text text-anchor='middle' x='48' y='20' fill='currentColor' style='font-size:1em'>o&lt;/text>
&lt;text text-anchor='middle' x='48' y='36' fill='currentColor' style='font-size:1em'>[&lt;/text>
&lt;text text-anchor='middle' x='56' y='20' fill='currentColor' style='font-size:1em'>c&lt;/text>
&lt;text text-anchor='middle' x='56' y='36' fill='currentColor' style='font-size:1em'>_&lt;/text>
&lt;text text-anchor='middle' x='64' y='20' fill='currentColor' style='font-size:1em'>k&lt;/text>
&lt;text text-anchor='middle' x='64' y='36' fill='currentColor' style='font-size:1em'>_&lt;/text>
&lt;text text-anchor='middle' x='72' y='20' fill='currentColor' style='font-size:1em'>u&lt;/text>
&lt;text text-anchor='middle' x='72' y='36' fill='currentColor' style='font-size:1em'>_&lt;/text>
&lt;text text-anchor='middle' x='80' y='20' fill='currentColor' style='font-size:1em'>p&lt;/text>
&lt;text text-anchor='middle' x='80' y='36' fill='currentColor' style='font-size:1em'>]&lt;/text>
&lt;text text-anchor='middle' x='152' y='20' fill='currentColor' style='font-size:1em'>C&lt;/text>
&lt;text text-anchor='middle' x='152' y='36' fill='currentColor' style='font-size:1em'>{&lt;/text>
&lt;text text-anchor='middle' x='160' y='20' fill='currentColor' style='font-size:1em'>o&lt;/text>
&lt;text text-anchor='middle' x='160' y='36' fill='currentColor' style='font-size:1em'>_&lt;/text>
&lt;text text-anchor='middle' x='168' y='20' fill='currentColor' style='font-size:1em'>d&lt;/text>
&lt;text text-anchor='middle' x='168' y='36' fill='currentColor' style='font-size:1em'>_&lt;/text>
&lt;text text-anchor='middle' x='176' y='20' fill='currentColor' style='font-size:1em'>e&lt;/text>
&lt;text text-anchor='middle' x='176' y='36' fill='currentColor' style='font-size:1em'>_&lt;/text>
&lt;text text-anchor='middle' x='184' y='36' fill='currentColor' style='font-size:1em'>}&lt;/text>
&lt;text text-anchor='middle' x='248' y='20' fill='currentColor' style='font-size:1em'>D&lt;/text>
&lt;text text-anchor='middle' x='248' y='68' fill='currentColor' style='font-size:1em'>C&lt;/text>
&lt;text text-anchor='middle' x='248' y='84' fill='currentColor' style='font-size:1em'>B&lt;/text>
&lt;text text-anchor='middle' x='248' y='100' fill='currentColor' style='font-size:1em'>E&lt;/text>
&lt;text text-anchor='middle' x='248' y='116' fill='currentColor' style='font-size:1em'>A&lt;/text>
&lt;text text-anchor='middle' x='256' y='20' fill='currentColor' style='font-size:1em'>I&lt;/text>
&lt;text text-anchor='middle' x='256' y='68' fill='currentColor' style='font-size:1em'>r&lt;/text>
&lt;text text-anchor='middle' x='256' y='84' fill='currentColor' style='font-size:1em'>u&lt;/text>
&lt;text text-anchor='middle' x='256' y='100' fill='currentColor' style='font-size:1em'>d&lt;/text>
&lt;text text-anchor='middle' x='256' y='116' fill='currentColor' style='font-size:1em'>n&lt;/text>
&lt;text text-anchor='middle' x='264' y='20' fill='currentColor' style='font-size:1em'>S&lt;/text>
&lt;text text-anchor='middle' x='264' y='36' fill='currentColor' style='font-size:1em'>💥&lt;/text>
&lt;text text-anchor='middle' x='264' y='68' fill='currentColor' style='font-size:1em'>a&lt;/text>
&lt;text text-anchor='middle' x='264' y='84' fill='currentColor' style='font-size:1em'>g&lt;/text>
&lt;text text-anchor='middle' x='264' y='100' fill='currentColor' style='font-size:1em'>g&lt;/text>
&lt;text text-anchor='middle' x='264' y='116' fill='currentColor' style='font-size:1em'>g&lt;/text>
&lt;text text-anchor='middle' x='272' y='20' fill='currentColor' style='font-size:1em'>A&lt;/text>
&lt;text text-anchor='middle' x='272' y='68' fill='currentColor' style='font-size:1em'>s&lt;/text>
&lt;text text-anchor='middle' x='272' y='84' fill='currentColor' style='font-size:1em'>s&lt;/text>
&lt;text text-anchor='middle' x='272' y='100' fill='currentColor' style='font-size:1em'>e&lt;/text>
&lt;text text-anchor='middle' x='272' y='116' fill='currentColor' style='font-size:1em'>r&lt;/text>
&lt;text text-anchor='middle' x='280' y='20' fill='currentColor' style='font-size:1em'>S&lt;/text>
&lt;text text-anchor='middle' x='280' y='68' fill='currentColor' style='font-size:1em'>h&lt;/text>
&lt;text text-anchor='middle' x='280' y='116' fill='currentColor' style='font-size:1em'>y&lt;/text>
&lt;text text-anchor='middle' x='288' y='20' fill='currentColor' style='font-size:1em'>T&lt;/text>
&lt;text text-anchor='middle' x='288' y='68' fill='currentColor' style='font-size:1em'>e&lt;/text>
&lt;text text-anchor='middle' x='288' y='100' fill='currentColor' style='font-size:1em'>C&lt;/text>
&lt;text text-anchor='middle' x='296' y='20' fill='currentColor' style='font-size:1em'>E&lt;/text>
&lt;text text-anchor='middle' x='296' y='68' fill='currentColor' style='font-size:1em'>s&lt;/text>
&lt;text text-anchor='middle' x='296' y='100' fill='currentColor' style='font-size:1em'>a&lt;/text>
&lt;text text-anchor='middle' x='296' y='116' fill='currentColor' style='font-size:1em'>U&lt;/text>
&lt;text text-anchor='middle' x='304' y='20' fill='currentColor' style='font-size:1em'>R&lt;/text>
&lt;text text-anchor='middle' x='304' y='100' fill='currentColor' style='font-size:1em'>s&lt;/text>
&lt;text text-anchor='middle' x='304' y='116' fill='currentColor' style='font-size:1em'>s&lt;/text>
&lt;text text-anchor='middle' x='312' y='20' fill='currentColor' style='font-size:1em'>!&lt;/text>
&lt;text text-anchor='middle' x='312' y='100' fill='currentColor' style='font-size:1em'>e&lt;/text>
&lt;text text-anchor='middle' x='312' y='116' fill='currentColor' style='font-size:1em'>e&lt;/text>
&lt;text text-anchor='middle' x='320' y='100' fill='currentColor' style='font-size:1em'>s&lt;/text>
&lt;text text-anchor='middle' x='320' y='116' fill='currentColor' style='font-size:1em'>r&lt;/text>
&lt;text text-anchor='middle' x='328' y='116' fill='currentColor' style='font-size:1em'>s&lt;/text>
&lt;/g>
&lt;/svg>
&lt;/div>
&lt;div style="max-width: 550px; color: var(--link-color-active); transform: rotate(-5deg); margin: auto" class="goat svg-container">
&lt;svg xmlns="http://www.w3.org/2000/svg"
font-family="Menlo, Lucida Console,monospace"
viewBox="0 0 456 153">
&lt;g transform='translate(8,16)'>
&lt;path d='M 96,16 L 136,16' fill='none' stroke='currentColor'>&lt;/path>
&lt;path d='M 232,16 L 272,16' fill='none' stroke='currentColor'>&lt;/path>
&lt;path d='M 328,16 L 368,16' fill='none' stroke='currentColor'>&lt;/path>
&lt;path d='M 56,48 L 56,112' fill='none' stroke='currentColor'>&lt;/path>
&lt;path d='M 168,40 L 168,56' fill='none' stroke='currentColor'>&lt;/path>
&lt;path d='M 280,48 L 280,112' fill='none' stroke='currentColor'>&lt;/path>
&lt;path d='M 384,40 L 384,56' fill='none' stroke='currentColor'>&lt;/path>
&lt;polygon points='144.000000,16.000000 132.000000,10.400000 132.000000,21.600000' fill='currentColor' transform='rotate(0.000000, 136.000000, 16.000000)'>&lt;/polygon>
&lt;polygon points='280.000000,16.000000 268.000000,10.400000 268.000000,21.600000' fill='currentColor' transform='rotate(0.000000, 272.000000, 16.000000)'>&lt;/polygon>
&lt;polygon points='376.000000,16.000000 364.000000,10.400000 364.000000,21.600000' fill='currentColor' transform='rotate(0.000000, 368.000000, 16.000000)'>&lt;/polygon>
&lt;text text-anchor='middle' x='40' y='20' fill='currentColor' style='font-size:1em'>M&lt;/text>
&lt;text text-anchor='middle' x='48' y='20' fill='currentColor' style='font-size:1em'>o&lt;/text>
&lt;text text-anchor='middle' x='48' y='36' fill='currentColor' style='font-size:1em'>[&lt;/text>
&lt;text text-anchor='middle' x='56' y='20' fill='currentColor' style='font-size:1em'>c&lt;/text>
&lt;text text-anchor='middle' x='56' y='36' fill='currentColor' style='font-size:1em'>_&lt;/text>
&lt;text text-anchor='middle' x='64' y='20' fill='currentColor' style='font-size:1em'>k&lt;/text>
&lt;text text-anchor='middle' x='64' y='36' fill='currentColor' style='font-size:1em'>_&lt;/text>
&lt;text text-anchor='middle' x='72' y='20' fill='currentColor' style='font-size:1em'>u&lt;/text>
&lt;text text-anchor='middle' x='72' y='36' fill='currentColor' style='font-size:1em'>_&lt;/text>
&lt;text text-anchor='middle' x='80' y='20' fill='currentColor' style='font-size:1em'>p&lt;/text>
&lt;text text-anchor='middle' x='80' y='36' fill='currentColor' style='font-size:1em'>]&lt;/text>
&lt;text text-anchor='middle' x='144' y='68' fill='currentColor' style='font-size:1em'>L&lt;/text>
&lt;text text-anchor='middle' x='144' y='84' fill='currentColor' style='font-size:1em'>M&lt;/text>
&lt;text text-anchor='middle' x='144' y='100' fill='currentColor' style='font-size:1em'>E&lt;/text>
&lt;text text-anchor='middle' x='144' y='116' fill='currentColor' style='font-size:1em'>E&lt;/text>
&lt;text text-anchor='middle' x='152' y='20' fill='currentColor' style='font-size:1em'>Q&lt;/text>
&lt;text text-anchor='middle' x='152' y='68' fill='currentColor' style='font-size:1em'>o&lt;/text>
&lt;text text-anchor='middle' x='152' y='84' fill='currentColor' style='font-size:1em'>o&lt;/text>
&lt;text text-anchor='middle' x='152' y='100' fill='currentColor' style='font-size:1em'>r&lt;/text>
&lt;text text-anchor='middle' x='152' y='116' fill='currentColor' style='font-size:1em'>m&lt;/text>
&lt;text text-anchor='middle' x='160' y='20' fill='currentColor' style='font-size:1em'>u&lt;/text>
&lt;text text-anchor='middle' x='160' y='36' fill='currentColor' style='font-size:1em'>?&lt;/text>
&lt;text text-anchor='middle' x='160' y='68' fill='currentColor' style='font-size:1em'>a&lt;/text>
&lt;text text-anchor='middle' x='160' y='84' fill='currentColor' style='font-size:1em'>b&lt;/text>
&lt;text text-anchor='middle' x='160' y='100' fill='currentColor' style='font-size:1em'>r&lt;/text>
&lt;text text-anchor='middle' x='160' y='116' fill='currentColor' style='font-size:1em'>p&lt;/text>
&lt;text text-anchor='middle' x='168' y='20' fill='currentColor' style='font-size:1em'>e&lt;/text>
&lt;text text-anchor='middle' x='168' y='68' fill='currentColor' style='font-size:1em'>d&lt;/text>
&lt;text text-anchor='middle' x='168' y='84' fill='currentColor' style='font-size:1em'>i&lt;/text>
&lt;text text-anchor='middle' x='168' y='100' fill='currentColor' style='font-size:1em'>o&lt;/text>
&lt;text text-anchor='middle' x='168' y='116' fill='currentColor' style='font-size:1em'>t&lt;/text>
&lt;text text-anchor='middle' x='176' y='20' fill='currentColor' style='font-size:1em'>s&lt;/text>
&lt;text text-anchor='middle' x='176' y='36' fill='currentColor' style='font-size:1em'>?&lt;/text>
&lt;text text-anchor='middle' x='176' y='68' fill='currentColor' style='font-size:1em'>i&lt;/text>
&lt;text text-anchor='middle' x='176' y='84' fill='currentColor' style='font-size:1em'>l&lt;/text>
&lt;text text-anchor='middle' x='176' y='100' fill='currentColor' style='font-size:1em'>r&lt;/text>
&lt;text text-anchor='middle' x='176' y='116' fill='currentColor' style='font-size:1em'>y&lt;/text>
&lt;text text-anchor='middle' x='184' y='20' fill='currentColor' style='font-size:1em'>t&lt;/text>
&lt;text text-anchor='middle' x='184' y='68' fill='currentColor' style='font-size:1em'>n&lt;/text>
&lt;text text-anchor='middle' x='184' y='84' fill='currentColor' style='font-size:1em'>e&lt;/text>
&lt;text text-anchor='middle' x='184' y='100' fill='currentColor' style='font-size:1em'>s&lt;/text>
&lt;text text-anchor='middle' x='184' y='116' fill='currentColor' style='font-size:1em'>?&lt;/text>
&lt;text text-anchor='middle' x='192' y='20' fill='currentColor' style='font-size:1em'>i&lt;/text>
&lt;text text-anchor='middle' x='192' y='36' fill='currentColor' style='font-size:1em'>?&lt;/text>
&lt;text text-anchor='middle' x='192' y='68' fill='currentColor' style='font-size:1em'>g&lt;/text>
&lt;text text-anchor='middle' x='192' y='84' fill='currentColor' style='font-size:1em'>?&lt;/text>
&lt;text text-anchor='middle' x='192' y='100' fill='currentColor' style='font-size:1em'>?&lt;/text>
&lt;text text-anchor='middle' x='200' y='20' fill='currentColor' style='font-size:1em'>o&lt;/text>
&lt;text text-anchor='middle' x='200' y='68' fill='currentColor' style='font-size:1em'>?&lt;/text>
&lt;text text-anchor='middle' x='208' y='20' fill='currentColor' style='font-size:1em'>n&lt;/text>
&lt;text text-anchor='middle' x='216' y='20' fill='currentColor' style='font-size:1em'>s&lt;/text>
&lt;text text-anchor='middle' x='272' y='36' fill='currentColor' style='font-size:1em'>{&lt;/text>
&lt;text text-anchor='middle' x='280' y='36' fill='currentColor' style='font-size:1em'>_&lt;/text>
&lt;text text-anchor='middle' x='288' y='20' fill='currentColor' style='font-size:1em'>C&lt;/text>
&lt;text text-anchor='middle' x='288' y='36' fill='currentColor' style='font-size:1em'>_&lt;/text>
&lt;text text-anchor='middle' x='296' y='20' fill='currentColor' style='font-size:1em'>o&lt;/text>
&lt;text text-anchor='middle' x='296' y='36' fill='currentColor' style='font-size:1em'>_&lt;/text>
&lt;text text-anchor='middle' x='304' y='20' fill='currentColor' style='font-size:1em'>d&lt;/text>
&lt;text text-anchor='middle' x='304' y='36' fill='currentColor' style='font-size:1em'>}&lt;/text>
&lt;text text-anchor='middle' x='312' y='20' fill='currentColor' style='font-size:1em'>e&lt;/text>
&lt;text text-anchor='middle' x='360' y='68' fill='currentColor' style='font-size:1em'>H&lt;/text>
&lt;text text-anchor='middle' x='360' y='84' fill='currentColor' style='font-size:1em'>S&lt;/text>
&lt;text text-anchor='middle' x='360' y='100' fill='currentColor' style='font-size:1em'>E&lt;/text>
&lt;text text-anchor='middle' x='360' y='116' fill='currentColor' style='font-size:1em'>H&lt;/text>
&lt;text text-anchor='middle' x='368' y='68' fill='currentColor' style='font-size:1em'>a&lt;/text>
&lt;text text-anchor='middle' x='368' y='84' fill='currentColor' style='font-size:1em'>t&lt;/text>
&lt;text text-anchor='middle' x='368' y='100' fill='currentColor' style='font-size:1em'>d&lt;/text>
&lt;text text-anchor='middle' x='368' y='116' fill='currentColor' style='font-size:1em'>a&lt;/text>
&lt;text text-anchor='middle' x='376' y='68' fill='currentColor' style='font-size:1em'>p&lt;/text>
&lt;text text-anchor='middle' x='376' y='84' fill='currentColor' style='font-size:1em'>a&lt;/text>
&lt;text text-anchor='middle' x='376' y='100' fill='currentColor' style='font-size:1em'>g&lt;/text>
&lt;text text-anchor='middle' x='376' y='116' fill='currentColor' style='font-size:1em'>n&lt;/text>
&lt;text text-anchor='middle' x='384' y='20' fill='currentColor' style='font-size:1em'>S&lt;/text>
&lt;text text-anchor='middle' x='384' y='36' fill='currentColor' style='font-size:1em'>🎉&lt;/text>
&lt;text text-anchor='middle' x='384' y='68' fill='currentColor' style='font-size:1em'>p&lt;/text>
&lt;text text-anchor='middle' x='384' y='84' fill='currentColor' style='font-size:1em'>b&lt;/text>
&lt;text text-anchor='middle' x='384' y='100' fill='currentColor' style='font-size:1em'>e&lt;/text>
&lt;text text-anchor='middle' x='384' y='116' fill='currentColor' style='font-size:1em'>d&lt;/text>
&lt;text text-anchor='middle' x='392' y='20' fill='currentColor' style='font-size:1em'>U&lt;/text>
&lt;text text-anchor='middle' x='392' y='68' fill='currentColor' style='font-size:1em'>y&lt;/text>
&lt;text text-anchor='middle' x='392' y='84' fill='currentColor' style='font-size:1em'>l&lt;/text>
&lt;text text-anchor='middle' x='392' y='116' fill='currentColor' style='font-size:1em'>l&lt;/text>
&lt;text text-anchor='middle' x='400' y='20' fill='currentColor' style='font-size:1em'>C&lt;/text>
&lt;text text-anchor='middle' x='400' y='84' fill='currentColor' style='font-size:1em'>e&lt;/text>
&lt;text text-anchor='middle' x='400' y='100' fill='currentColor' style='font-size:1em'>C&lt;/text>
&lt;text text-anchor='middle' x='400' y='116' fill='currentColor' style='font-size:1em'>e&lt;/text>
&lt;text text-anchor='middle' x='408' y='20' fill='currentColor' style='font-size:1em'>C&lt;/text>
&lt;text text-anchor='middle' x='408' y='68' fill='currentColor' style='font-size:1em'>U&lt;/text>
&lt;text text-anchor='middle' x='408' y='100' fill='currentColor' style='font-size:1em'>a&lt;/text>
&lt;text text-anchor='middle' x='408' y='116' fill='currentColor' style='font-size:1em'>d&lt;/text>
&lt;text text-anchor='middle' x='416' y='20' fill='currentColor' style='font-size:1em'>E&lt;/text>
&lt;text text-anchor='middle' x='416' y='68' fill='currentColor' style='font-size:1em'>s&lt;/text>
&lt;text text-anchor='middle' x='416' y='84' fill='currentColor' style='font-size:1em'>A&lt;/text>
&lt;text text-anchor='middle' x='416' y='100' fill='currentColor' style='font-size:1em'>s&lt;/text>
&lt;text text-anchor='middle' x='424' y='20' fill='currentColor' style='font-size:1em'>S&lt;/text>
&lt;text text-anchor='middle' x='424' y='68' fill='currentColor' style='font-size:1em'>e&lt;/text>
&lt;text text-anchor='middle' x='424' y='84' fill='currentColor' style='font-size:1em'>p&lt;/text>
&lt;text text-anchor='middle' x='424' y='100' fill='currentColor' style='font-size:1em'>e&lt;/text>
&lt;text text-anchor='middle' x='432' y='20' fill='currentColor' style='font-size:1em'>S&lt;/text>
&lt;text text-anchor='middle' x='432' y='68' fill='currentColor' style='font-size:1em'>r&lt;/text>
&lt;text text-anchor='middle' x='432' y='84' fill='currentColor' style='font-size:1em'>p&lt;/text>
&lt;text text-anchor='middle' x='432' y='100' fill='currentColor' style='font-size:1em'>s&lt;/text>
&lt;text text-anchor='middle' x='440' y='20' fill='currentColor' style='font-size:1em'>!&lt;/text>
&lt;text text-anchor='middle' x='440' y='68' fill='currentColor' style='font-size:1em'>s&lt;/text>
&lt;/g>
&lt;/svg>
&lt;/div>
&lt;/div>
&lt;/div>
&lt;/p>
&lt;div id="outline-container-headline-2" class="outline-3">
&lt;h3 id="headline-2">
A design checklist for developers
&lt;/h3>
&lt;div id="outline-text-headline-2" class="outline-text-3">
&lt;p>
The key to delivering smiles instead of stress is realistic estimation. You need to account for everything - not just what&amp;#39;s visible in those perfectly crafted Figma files. Without this knowledge, you&amp;#39;ll find yourself days before delivery, discovering whole new categories of work nobody planned for.&lt;/p>
&lt;p>
I&amp;#39;ve seen this play out countless times: the mockup shows a beautifully designed dashboard with sample data perfectly laid out. But what happens when:
An admin accidentally deletes a critical record&lt;/p>
&lt;ul>
&lt;li>The user has 10x more items than the design shows&lt;/li>
&lt;li>Someone&amp;#39;s name is in Korean and breaks the layout&lt;/li>
&lt;li>The data is empty, slow to arrive, or malformed&lt;/li>
&lt;li>The user is on a slow mobile connection&lt;/li>
&lt;li>Someone needs to navigate the interface with a screen reader&lt;/li>
&lt;/ul>
&lt;p>These aren&amp;#39;t edge cases - they&amp;#39;re the reality of how people will use your application. And accounting for them up front is the difference between a smooth delivery and a last-minute scramble.&lt;/p>
&lt;p>
Over the years, I&amp;#39;ve developed a systematic approach to reviewing designs. Here&amp;#39;s my battle-tested checklist that helps surface these requirements early. I&amp;#39;ve organized it by major concern areas, but feel free to adapt it to your workflow.&lt;/p>
&lt;div id="outline-container-headline-3" class="outline-4">
&lt;h4 id="headline-3">
The Checklist
&lt;/h4>
&lt;div id="outline-text-headline-3" class="outline-text-4">
&lt;p>
&lt;em>Layout Structure&lt;/em> — The foundation of any interface is its layout structure. Getting this right early is crucial because it affects everything else. Layout decisions impact both the visual hierarchy and the technical implementation approach. Here&amp;#39;s what to clarify:&lt;/p>
&lt;table>
&lt;tbody>
&lt;tr>
&lt;td>&lt;strong>&lt;strong>Base layout composition and hierarchy&lt;/strong>&lt;/strong>&lt;/td>
&lt;td>What are the major layout regions/sections?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>How do sections relate spatially to each other?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>What grid system or layout technique should be used?&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;tbody>
&lt;tr>
&lt;td>&lt;strong>&lt;strong>Responsive behavior&lt;/strong>&lt;/strong>&lt;/td>
&lt;td>At what pixel widths do layouts change?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>Which elements reflow vs hide on mobile?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>How do navigation elements transform at breakpoints?&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;tbody>
&lt;tr>
&lt;td>&lt;strong>&lt;strong>Panel sizing/interactions&lt;/strong>&lt;/strong>&lt;/td>
&lt;td>Are panels resizable?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>What are min/max dimensions?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>How do panels behave when content overflows?&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;tbody>
&lt;tr>
&lt;td>&lt;strong>&lt;strong>Overflow handling&lt;/strong>&lt;/strong>&lt;/td>
&lt;td>Which containers should scroll?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>Is scroll behavior smooth or standard?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>Are there sticky elements during scroll?&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;tbody>
&lt;tr>
&lt;td>&lt;strong>&lt;strong>Loading states&lt;/strong>&lt;/strong>&lt;/td>
&lt;td>Which regions show loading indicators?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>Are there placeholder layouts while loading?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>How do loading states affect layout stability?&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>
&lt;em>Input Elements&lt;/em> — Forms and input elements are where users directly interact with your application. They&amp;#39;re also notorious for having complex state management and validation requirements. Every input needs careful consideration of its various states and behaviors:&lt;/p>
&lt;table>
&lt;tbody>
&lt;tr>
&lt;td>&lt;strong>&lt;strong>Visual states&lt;/strong>&lt;/strong>&lt;/td>
&lt;td>What color/style changes on hover?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>How is focus indicated visually?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>What visual feedback shows disabled state?&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;tbody>
&lt;tr>
&lt;td>&lt;strong>&lt;strong>Validation states&lt;/strong>&lt;/strong>&lt;/td>
&lt;td>Where do error messages appear?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>How are required fields indicated?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>What triggers validation checks?&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;tbody>
&lt;tr>
&lt;td>&lt;strong>&lt;strong>Label/text sourcing&lt;/strong>&lt;/strong>&lt;/td>
&lt;td>Are there placeholder values?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>Do any labels update dynamically?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>Where are text strings stored/managed?&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>
&lt;em>Text Content&lt;/em> — Text content is deceptively complex. It&amp;#39;s not just about displaying strings - it&amp;#39;s about handling dynamic content that can vary wildly in length, language, and format. These requirements help prevent layout breaks and poor user experience:&lt;/p>
&lt;table>
&lt;tbody>
&lt;tr>
&lt;td>&lt;strong>&lt;strong>Content source&lt;/strong>&lt;/strong>&lt;/td>
&lt;td>What API endpoints provide text?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>How often does content update?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>Is content cached client-side?&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;tbody>
&lt;tr>
&lt;td>&lt;strong>&lt;strong>Loading states&lt;/strong>&lt;/strong>&lt;/td>
&lt;td>Should skeleton layouts match content shape?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>What placeholder width/heights to use?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>When do loading indicators appear/disappear?&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;tbody>
&lt;tr>
&lt;td>&lt;strong>&lt;strong>Truncation handling&lt;/strong>&lt;/strong>&lt;/td>
&lt;td>At what width/height does text truncate?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>Is there a &amp;#34;show more&amp;#34; mechanism?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>How are long words handled?&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;tbody>
&lt;tr>
&lt;td>&lt;strong>&lt;strong>Empty states&lt;/strong>&lt;/strong>&lt;/td>
&lt;td>What message appears when no content exists?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>Are there suggested actions shown?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>How does empty state affect layout?&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>
&lt;em>Transient Elements&lt;/em> — Tooltips, modals, popovers, and other temporary UI elements need special attention. They often have complex triggering logic and need to play nice with other elements on the page. Here&amp;#39;s what to nail down:&lt;/p>
&lt;table>
&lt;tbody>
&lt;tr>
&lt;td>&lt;strong>&lt;strong>Trigger conditions&lt;/strong>&lt;/strong>&lt;/td>
&lt;td>What user actions show/hide the element?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>Is there a delay before showing/hiding?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>Can system events trigger the element?&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;tbody>
&lt;tr>
&lt;td>&lt;strong>&lt;strong>Animation specs&lt;/strong>&lt;/strong>&lt;/td>
&lt;td>What properties are animated?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>What timing functions are used?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>How do animations change on mobile?&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;tbody>
&lt;tr>
&lt;td>&lt;strong>&lt;strong>Coexistence rules&lt;/strong>&lt;/strong>&lt;/td>
&lt;td>Which elements can show simultaneously?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>Do elements affect each other&amp;#39;s position?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>How is z-index managed?&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>
&lt;em>Data Tables/Lists&lt;/em> — Tables and lists are where complex data interactions happen. They often need to handle sorting, filtering, and pagination while maintaining performance with large datasets. These questions help define the complete behavior:&lt;/p>
&lt;table>
&lt;tbody>
&lt;tr>
&lt;td>&lt;strong>&lt;strong>Sorting behavior&lt;/strong>&lt;/strong>&lt;/td>
&lt;td>Is initial sort order specified?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>Can multiple columns be sorted?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>How is sort direction indicated?&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;tbody>
&lt;tr>
&lt;td>&lt;strong>&lt;strong>Filtering mechanisms&lt;/strong>&lt;/strong>&lt;/td>
&lt;td>How do multiple filters combine?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>Is filter state preserved?&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;tbody>
&lt;tr>
&lt;td>&lt;strong>&lt;strong>Empty/loading states&lt;/strong>&lt;/strong>&lt;/td>
&lt;td>What appears during initial load?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>How is &amp;#34;no results&amp;#34; handled?&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>
&lt;em>Implied CRUD Features&lt;/em> — Almost every data-driven interface needs more than just the &amp;#34;happy path&amp;#34; shown in mockups. Create, Read, Update, Delete operations often come with a host of implied requirements that aren&amp;#39;t visible in the design but are essential for real-world usage:&lt;/p>
&lt;table>
&lt;tbody>
&lt;tr>
&lt;td>&lt;strong>&lt;strong>Record management&lt;/strong>&lt;/strong>&lt;/td>
&lt;td>How are new records created?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>Can records be archived instead of deleted?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>Is record cloning/duplication needed?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>What confirmation is required for destructive actions?&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;tbody>
&lt;tr>
&lt;td>&lt;strong>&lt;strong>Edit workflows&lt;/strong>&lt;/strong>&lt;/td>
&lt;td>Is inline editing supported?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>How are unsaved changes handled?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>What validation occurs before save?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>Can edits be reverted/cancelled?&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;tbody>
&lt;tr>
&lt;td>&lt;strong>&lt;strong>Audit requirements&lt;/strong>&lt;/strong>&lt;/td>
&lt;td>Are changes tracked with timestamps?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>Do we show who made changes?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>Is version history needed?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>How long is history retained?&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;tbody>
&lt;tr>
&lt;td>&lt;strong>&lt;strong>Batch operations&lt;/strong>&lt;/strong>&lt;/td>
&lt;td>Can multiple items be selected?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>What bulk actions are available?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>How is batch operation progress shown?&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;/td>
&lt;td>How are partial failures handled?&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;/div>
&lt;/div>
&lt;/div>
&lt;/div>
&lt;div id="outline-container-headline-4" class="outline-3">
&lt;h3 id="headline-4">
Using This Checklist
&lt;/h3>
&lt;div id="outline-text-headline-4" class="outline-text-3">
&lt;p>
Grab this checklist and run through it during your first design handoff meeting. It&amp;#39;s way better to figure this stuff out upfront than to discover halfway through development that nobody thought about what happens when the API times out.&lt;/p>
&lt;p>
These are the things that work for me, but feel free to adapt it to your needs.&lt;/p>
&lt;/div>
&lt;/div>
&lt;/div>
&lt;/div>
]]></content:encoded></item><item><title>A Tailwind-CSS development server</title><description> Simple quick way to get started learning and playing with Tailwind CSS
Example output while running dev-server, shown here: Features No "transpiling" configuration is needed (or used). No build tools need to be set up. Tiny reactive web server: ~115 lines of code with lots of comments. Minimal dependencies:
chalk for color, socket.io for server &lt;—> browser communication, and tailwindcss of course. Installation Clone the GIT repository, and install the dependencies.</description><link>https://khtdr.com/tailwind-css-dev-server.html</link><guid>https://khtdr.com/tailwind-css-dev-server.html</guid><pubDate>Mon, 07 Jan 2019 00:00:00 +0000</pubDate><category>Tutorials</category><content:encoded>
&lt;![CDATA[
&lt;blockquote>
&lt;p>Simple quick way to get started learning and playing with Tailwind CSS&lt;/p>
&lt;/blockquote>
&lt;p>
Example output while running dev-server, shown here: &lt;img src="https://khtdr.com/img/sample-logs.png" alt="/img/sample-logs.png" title="/img/sample-logs.png" />&lt;/p>
&lt;div id="outline-container-headline-1" class="outline-2">
&lt;h2 id="headline-1">
Features
&lt;/h2>
&lt;div id="outline-text-headline-1" class="outline-text-2">
&lt;ul>
&lt;li>No &amp;#34;transpiling&amp;#34; configuration is needed (or used).&lt;/li>
&lt;li>No build tools need to be set up.&lt;/li>
&lt;li>Tiny reactive web server: ~115 lines of code with lots of comments.&lt;/li>
&lt;li>
&lt;p>Minimal dependencies:&lt;/p>
&lt;ul>
&lt;li>&lt;code class="verbatim">chalk&lt;/code> for color,&lt;/li>
&lt;li>&lt;code class="verbatim">socket.io&lt;/code> for &lt;strong>server&lt;/strong> &amp;lt;—&amp;gt; &lt;strong>browser&lt;/strong> communication,&lt;/li>
&lt;li>and &lt;code class="verbatim">tailwindcss&lt;/code> of course.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/div>
&lt;/div>
&lt;div id="outline-container-headline-2" class="outline-2">
&lt;h2 id="headline-2">
Installation
&lt;/h2>
&lt;div id="outline-text-headline-2" class="outline-text-2">
&lt;p>Clone the GIT repository, and install the dependencies.&lt;/p>
&lt;div class="src src-bash">
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">git clone https://github.com/khtdr/tailwind-dev-server.git
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">cd&lt;/span> tailwind-dev-server
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">yarn&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/div>
&lt;/div>
&lt;/div>
&lt;div id="outline-container-headline-3" class="outline-2">
&lt;h2 id="headline-3">
Running
&lt;/h2>
&lt;div id="outline-text-headline-3" class="outline-text-2">
&lt;div class="src src-bash">
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">yarn start&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/div>
&lt;p>
Then open your browser to: &lt;a href="http://localhost:8080">http://localhost:8080&lt;/a>&lt;/p>
&lt;/div>
&lt;/div>
&lt;div id="outline-container-headline-4" class="outline-2">
&lt;h2 id="headline-4">
Development
&lt;/h2>
&lt;div id="outline-text-headline-4" class="outline-text-2">
&lt;p>
Edit any of the following entry point files:&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://github.com/khtdr/tailwind-dev-server/blob/master/index.html">./index.html&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://github.com/khtdr/tailwind-dev-server/blob/master/style.css">./style.css&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://github.com/khtdr/tailwind-dev-server/blob/master/tailwind.js">./tailwind.js&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>Changes will be recompiled and automatically refreshed in your browser. Errors will be displayed in the server output.&lt;/p>
&lt;p>
Create any additional HTML files as needed, using &lt;a href="https://github.com/khtdr/tailwind-dev-server/blob/master/index.html">./index.html&lt;/a> as a starting-point reference.&lt;/p>
&lt;/div>
&lt;/div>
&lt;div id="outline-container-headline-5" class="outline-2">
&lt;h2 id="headline-5">
Building
&lt;/h2>
&lt;div id="outline-text-headline-5" class="outline-text-2">
&lt;p>If you like what you see and want to save it and use it, run:&lt;/p>
&lt;div class="src src-bash">
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">yarn build&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/div>
&lt;p>
And now you can use your newly-built &lt;code class="verbatim">./tailwind-bundle.css&lt;/code> stylesheet however you like.&lt;/p>
&lt;/div>
&lt;/div>
]]></content:encoded></item><item><title>Dark-Mode Light-Mode Css</title><description> Use a media query to set different values for variables in dark-mode.
:root { --background-color: #eee; --text-color: #222; } @media (prefers-color-scheme: dark) { :root { --background-color: #222; --text-color: #eee; } } body { background-color: var(--background-color); color: var(--text-color); }</description><link>https://khtdr.com/dark-mode-light-mode-css.html</link><guid>https://khtdr.com/dark-mode-light-mode-css.html</guid><pubDate>Sun, 16 Aug 2020 18:53:52 -0600</pubDate><category>Snippets</category><content:encoded>
&lt;![CDATA[
&lt;p>
Use a media query to set different values for variables in dark-mode.&lt;/p>
&lt;div class="src src-css">
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-css" data-lang="css">&lt;span class="line">&lt;span class="cl">&lt;span class="p">:&lt;/span>&lt;span class="nd">root&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nv">--background-color&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mh">#eee&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nv">--text-color&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mh">#222&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">@&lt;/span>&lt;span class="k">media&lt;/span> &lt;span class="o">(&lt;/span>&lt;span class="nt">prefers-color-scheme&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="nt">dark&lt;/span>&lt;span class="o">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">:&lt;/span>&lt;span class="nd">root&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nv">--background-color&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mh">#222&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nv">--text-color&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mh">#eee&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nt">body&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">background-color&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="nf">var&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">--&lt;/span>&lt;span class="n">background&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="kc">color&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">color&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="nf">var&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">--&lt;/span>&lt;span class="kc">text&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="kc">color&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/div>
]]></content:encoded></item><item><title>pageboy</title><description> pageboy Write your shell scripts in any combination of scripting languages.
Example Script example.pb
#!/usr/bin/env pageboy echo in Bash $PAGE php echo back to Bash #!/usr/bin/env php &lt;?php echo "in PHP\n"; Running the following, produces:
chmod +x ./example.pb ./example.pb in Bash in PHP back to Bash You can mix and match all you want. If your script uses valid shebangs, it will work. If it doesn&rsquo;t, it&rsquo;s a bug and please let me know. It also supports the (not quite right) awk shebang: #!/usr/bin/env awk.</description><link>https://khtdr.com/pageboy.html</link><guid>https://khtdr.com/pageboy.html</guid><pubDate>Fri, 14 Aug 2020 18:46:11 -0600</pubDate><category>software</category><content:encoded>
&lt;![CDATA[
&lt;!-- raw HTML omitted -->
&lt;h2 id="pageboy">pageboy&lt;/h2>
&lt;p>Write your shell scripts in any combination of scripting languages.&lt;/p>
&lt;p>&lt;strong>Example Script&lt;/strong> &lt;code>example.pb&lt;/code>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#!/usr/bin/env pageboy
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>&lt;span class="nb">echo&lt;/span> in Bash
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">$PAGE&lt;/span> php
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">echo&lt;/span> back to Bash
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">#!/usr/bin/env php&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&amp;lt;?php &lt;span class="nb">echo&lt;/span> &lt;span class="s2">&amp;#34;in PHP\n&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Running the following, produces:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">chmod +x ./example.pb
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">./example.pb
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;pre>&lt;code>in Bash
in PHP
back to Bash
&lt;/code>&lt;/pre>
&lt;p>You can mix and match all you want. If your script uses valid &lt;a href="https://en.wikipedia.org/wiki/Shebang_(Unix)">shebangs&lt;/a>, it will work. If it doesn&amp;rsquo;t, it&amp;rsquo;s a bug and &lt;a href="https://github.com/khtdr/pageboy/issues">please let me know&lt;/a>. It also supports the (not quite right) awk shebang: &lt;code>#!/usr/bin/env awk&lt;/code>.&lt;/p>
&lt;h3 id="test-suite-status">Test suite status&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">./run-tests.sh
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;pre>&lt;code>pageboy-v2.1.3
./pageboy-test # runs as pageboy script
./pageboy-test -r &amp;lt;page&amp;gt; # runs requested page
./pageboy-test -p &amp;lt;page&amp;gt; # prints requested page
./pageboy-test -c # compiles to bash script
./pageboy-test -d # dumps page table
./pageboy-test -h # shows this message
https://github.com/khtdr/pageboy
./tests/aliased.pb ... passed
./tests/args.pb ... passed
./tests/awk.pb ... passed
./tests/confusing.pb ... passed
./tests/dump.pb ... passed
./tests/lots.pb ... passed
./tests/named.pb ... passed
./tests/pageboy.pb ... passed
./tests/paths.pb ... passed
./tests/plain-bash.pb ... passed
./tests/print-php.pb ... passed
./tests/pwd.pb ... passed
./tests/run-php.pb ... passed
./tests/version.pb ... passed
&lt;/code>&lt;/pre>
&lt;h2 id="installation--quickstart">Installation &amp;amp; quickstart&lt;/h2>
&lt;ol>
&lt;li>Current version: 2.1.3&lt;/li>
&lt;li>Download the &lt;a href="https://raw.githubusercontent.com/khtdr/pageboy/v1.2.3/pageboy">pageboy bash script&lt;/a> and put into your &lt;code>$PATH&lt;/code> (ie. &lt;code>~/bin/&lt;/code>).&lt;/li>
&lt;li>Start using &lt;code>#!/usr/bin/env pageboy&lt;/code> as your shebang line in your bash scripts.&lt;/li>
&lt;li>Call other &amp;ldquo;pages&amp;rdquo; of your script by using the pre-defined &lt;code>$PAGE&lt;/code> command in your scripts.&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#!/usr/bin/env pageboy
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>&lt;span class="nv">$PAGE&lt;/span> php &lt;span class="p">|&lt;/span> wc
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">#!/usr/bin/env php&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&amp;lt;?php
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">phpinfo&lt;span class="o">()&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;pre>&lt;code> 934 3524 29671
&lt;/code>&lt;/pre>
&lt;p>If you want multiple pages of the same language, append an index, starting at 1, to the pagename.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#!/usr/bin/env pageboy
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>cat &amp;lt;&lt;span class="o">(&lt;/span>&lt;span class="nv">$PAGE&lt;/span> php1&lt;span class="o">)&lt;/span> &amp;lt;&lt;span class="o">(&lt;/span>&lt;span class="nv">$PAGE&lt;/span> php2&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">#!/usr/bin/env php&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&amp;lt;?php &lt;span class="nb">echo&lt;/span> &lt;span class="s2">&amp;#34;one&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">#!/usr/bin/env php&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&amp;lt;?php &lt;span class="nb">echo&lt;/span> &lt;span class="s2">&amp;#34;two&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;pre>&lt;code>onetwo
&lt;/code>&lt;/pre>
&lt;p>You can distribute a version of your script without the dependency on &lt;code>pageboy&lt;/code> by compiling it:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># copy above into `onetwo.pb`&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">onetwo.pb -c &amp;gt; onetwo.sh
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">chmod +x ./onetwo.sh
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">./onetwo.sh
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;pre>&lt;code>onetwo
&lt;/code>&lt;/pre>
&lt;p>&lt;strong>Big Example&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#!/usr/bin/env pageboy
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>cat &amp;lt;&lt;span class="o">(&lt;/span>&lt;span class="nv">$PAGE&lt;/span> php&lt;span class="o">)&lt;/span> &amp;lt;&lt;span class="o">(&lt;/span>&lt;span class="nv">$PAGE&lt;/span> ruby&lt;span class="o">)&lt;/span> &amp;lt;&lt;span class="o">(&lt;/span>&lt;span class="nv">$PAGE&lt;/span> bash1&lt;span class="o">)&lt;/span> &amp;lt;&lt;span class="o">(&lt;/span>&lt;span class="nv">$PAGE&lt;/span> bash2&lt;span class="o">)&lt;/span> &amp;lt;&lt;span class="o">(&lt;/span>&lt;span class="nv">$PAGE&lt;/span> php2&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">#!/usr/bin/env php&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&amp;lt;?php
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">for&lt;/span> &lt;span class="o">(&lt;/span>&lt;span class="nv">$i&lt;/span>&lt;span class="o">=&lt;/span>10&lt;span class="p">;&lt;/span> &lt;span class="nv">$i&lt;/span>&amp;lt;&lt;span class="o">=&lt;/span>20&lt;span class="p">;&lt;/span> &lt;span class="nv">$i&lt;/span>++&lt;span class="o">)&lt;/span> &lt;span class="o">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">echo&lt;/span> &lt;span class="nv">$i&lt;/span> . &lt;span class="s2">&amp;#34;\n&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">#!/usr/bin/env ruby&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">5.times &lt;span class="k">do&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> puts &lt;span class="s2">&amp;#34;Hello, World! ~ruby1&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">end
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">#!/bin/bash&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">echo&lt;/span> &lt;span class="s2">&amp;#34;Hello, World! ~bash2&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">whoami
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">#!/usr/bin/env bash&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">env &lt;span class="p">|&lt;/span> grep TERM
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">#!/usr/bin/env php&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&amp;lt;?php
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">echo&lt;/span> __DIR__&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;pre>&lt;code>10
11
12
13
14
15
16
17
18
19
20
Hello, World! ~ruby1
Hello, World! ~ruby1
Hello, World! ~ruby1
Hello, World! ~ruby1
Hello, World! ~ruby1
Hello, World! ~bash2
khtdr
TERM_PROGRAM=iTerm.app
TERM=xterm-256color
ITERM_PROFILE=Default
ITERM_SESSION_ID=w0t0p0
/home/khtdr/
&lt;/code>&lt;/pre>
&lt;h2 id="standard-features">Standard features&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">pageboy -h
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;pre>&lt;code>pageboy-v2.1.3
pageboy # runs as pageboy script
pageboy -r &amp;lt;page&amp;gt; # runs requested page
pageboy -p &amp;lt;page&amp;gt; # prints requested page
pageboy -c # compiles to bash script
pageboy -d # dumps page table
pageboy -h # shows this message
https://github.com/khtdr/pageboy
&lt;/code>&lt;/pre>
&lt;p>More examples can be found in the &lt;a href="https://github.com/khtdr/pageboy/blob/master/tests/">tests directory&lt;/a>.&lt;/p>
&lt;h2 id="advanced-features">Advanced features&lt;/h2>
&lt;ul>
&lt;li>Pages can be named, see &lt;a href="https://github.com/khtdr/pageboy/blob/master/tests/named.pb">pageboy/tests/named.pb&lt;/a>&lt;/li>
&lt;li>Args can be passed in, see &lt;a href="https://github.com/khtdr/pageboy/blob/master/tests/args.pb">pageboy/tests/args.pb&lt;/a>&lt;/li>
&lt;/ul>
&lt;blockquote>
&lt;p>The full source code and examples are available at: &lt;a href="https://github.com/khtdr/pageboy">khtdr/pageboy&lt;/a>&lt;/p>
&lt;/blockquote>
]]></content:encoded></item><item><title>treeify-paths</title><description>Introduction Useful when converting a list of file names into a nested UL/LI tree. Perfect for site maps, and directory listings.
Provide a list of file names:
blog/all.html blog/2036/overflows.html And recieve a directory-like tree:
blog all.html 2036 overflows.html Installation Install it with NPM:
npm install --save treeify-paths Import with modern syntax:
import treeifyPaths from "treeify-paths"; Or if you are not using NPM, install the library by downloading the source file directly and including it in your project:</description><link>https://khtdr.com/treeify-paths.html</link><guid>https://khtdr.com/treeify-paths.html</guid><pubDate>Fri, 14 Aug 2020 18:46:11 -0600</pubDate><category>software</category><content:encoded>
&lt;![CDATA[
&lt;h2 id="introduction">Introduction&lt;/h2>
&lt;p>Useful when converting a list of file names into a nested UL/LI tree. Perfect for site maps, and directory listings.&lt;/p>
&lt;p>Provide a &lt;strong>list of file names&lt;/strong>:&lt;/p>
&lt;ul>
&lt;li>blog/all.html&lt;/li>
&lt;li>blog/2036/overflows.html&lt;/li>
&lt;/ul>
&lt;p>And recieve a &lt;strong>directory-like tree&lt;/strong>:&lt;/p>
&lt;ul>
&lt;li>blog
&lt;ul>
&lt;li>all.html&lt;/li>
&lt;li>2036
&lt;ul>
&lt;li>overflows.html&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h2 id="installation">Installation&lt;/h2>
&lt;p>Install it with NPM:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">npm install --save treeify-paths
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Import with modern syntax:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="kr">import&lt;/span> &lt;span class="nx">treeifyPaths&lt;/span> &lt;span class="nx">from&lt;/span> &lt;span class="s2">&amp;#34;treeify-paths&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;em>Or&lt;/em> if you are not using NPM, install the library by downloading the &lt;a href="https://raw.githubusercontent.com/khtdr/treeify-paths/master/dist/treeify-paths.js">source file&lt;/a> directly and including it in your project:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">curl -o treeify-paths.js &lt;span class="s2">&amp;#34;https://raw.githubusercontent.com/khtdr/treeify-paths/blob/master/dist/treeify-paths.js&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Load with classic syntax:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="kd">let&lt;/span> &lt;span class="nx">treeify_paths&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">require&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;./treeify-paths&amp;#34;&lt;/span>&lt;span class="p">).&lt;/span>&lt;span class="k">default&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The library itself is written in &lt;a href="https://raw.githubusercontent.com/khtdr/treeify-paths/master/treeify-paths.ts">a few lines of typescript&lt;/a>.&lt;/p>
&lt;h2 id="example-usage">Example Usage&lt;/h2>
&lt;p>This module provides a function &lt;code>treeifyPaths&lt;/code> that takes a list of file names and returns a directory-like tree.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-typescript" data-lang="typescript">&lt;span class="line">&lt;span class="cl">&lt;span class="kr">type&lt;/span> &lt;span class="nx">Tree&lt;/span> &lt;span class="o">:&lt;/span>&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">path&lt;/span> :&lt;span class="kt">string&lt;/span> &lt;span class="c1">// full path to this node
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">name&lt;/span> :&lt;span class="kt">string&lt;/span> &lt;span class="c1">// name of this leaf
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">children&lt;/span> :&lt;span class="kt">Tree&lt;/span>&lt;span class="p">[]&lt;/span> &lt;span class="c1">// sub tree of trees and leaves
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">treeifyPaths&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">paths&lt;/span> :&lt;span class="kt">string&lt;/span>&lt;span class="p">[])&lt;/span> &lt;span class="o">=&amp;gt;&lt;/span> &lt;span class="o">:&lt;/span>&lt;span class="nx">Tree&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>This example produces prints the following output:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="kr">import&lt;/span> &lt;span class="nx">treeifyPaths&lt;/span> &lt;span class="nx">from&lt;/span> &lt;span class="s1">&amp;#39;treeify-paths&amp;#39;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">JSON&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">stringify&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">treeifyPaths&lt;/span>&lt;span class="p">([&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;about.html&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;careers&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;careers/job-1.html&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;careers/job-2.html&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;to/some/page.aspx&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">]),&lt;/span> &lt;span class="kc">null&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">3&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;pre>&lt;code>{
&amp;quot;path&amp;quot;: &amp;quot;&amp;quot;,
&amp;quot;name&amp;quot;: &amp;quot;&amp;quot;,
&amp;quot;children&amp;quot;: [
{
&amp;quot;path&amp;quot;: &amp;quot;about.html&amp;quot;,
&amp;quot;name&amp;quot;: &amp;quot;about.html&amp;quot;,
&amp;quot;children&amp;quot;: []
},
{
&amp;quot;path&amp;quot;: &amp;quot;careers&amp;quot;,
&amp;quot;name&amp;quot;: &amp;quot;careers&amp;quot;,
&amp;quot;children&amp;quot;: [
{
&amp;quot;path&amp;quot;: &amp;quot;careers/job-1.html&amp;quot;,
&amp;quot;name&amp;quot;: &amp;quot;job-1.html&amp;quot;,
&amp;quot;children&amp;quot;: []
},
{
&amp;quot;path&amp;quot;: &amp;quot;careers/job-2.html&amp;quot;,
&amp;quot;name&amp;quot;: &amp;quot;job-2.html&amp;quot;,
&amp;quot;children&amp;quot;: []
}
]
},
{
&amp;quot;path&amp;quot;: &amp;quot;to&amp;quot;,
&amp;quot;name&amp;quot;: &amp;quot;&amp;quot;,
&amp;quot;children&amp;quot;: [
{
&amp;quot;path&amp;quot;: &amp;quot;to/some&amp;quot;,
&amp;quot;name&amp;quot;: &amp;quot;&amp;quot;,
&amp;quot;children&amp;quot;: [
{
&amp;quot;path&amp;quot;: &amp;quot;to/some/page.aspx&amp;quot;,
&amp;quot;name&amp;quot;: &amp;quot;page.aspx&amp;quot;,
&amp;quot;children&amp;quot;: []
}
]
}
]
}
]
}
&lt;/code>&lt;/pre>
&lt;p>&lt;strong>Online Interactive Examples&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://runkit.com/khtdr/treeify-paths">Live example&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://runkit.com/downloads/khtdr/treeify-paths/1.0.0.zip">Download example&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="testing">Testing&lt;/h2>
&lt;p>The mocha &lt;a href="https://github.com/khtdr/treeify-paths/blob/master/tests.js">tests have many examples&lt;/a>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&amp;gt; treeify-paths@1.0.2 pretest khtdr/treeify-paths
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&amp;gt; tsc lib.ts &lt;span class="o">&amp;amp;&amp;amp;&lt;/span> mv lib.js treeify-paths.js
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&amp;gt; treeify-paths@1.0.2 &lt;span class="nb">test&lt;/span> khtdr/treeify-paths
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&amp;gt; mocha tests.js
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> treeifyPaths&lt;span class="o">([&lt;/span>...arguments&lt;span class="o">])&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> arguments: none
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ✓ should &lt;span class="k">return&lt;/span> an empty object
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> arguments: empty list
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ✓ should &lt;span class="k">return&lt;/span> an empty object
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> arguments: list with a single file
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ✓ should &lt;span class="k">return&lt;/span> a single file
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ✓ should &lt;span class="k">return&lt;/span> with nested children
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> arguments: multiple file names
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ✓ should &lt;span class="k">return&lt;/span> with nested children
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ✓ should alphabetize
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ✓ should ignore duplicates
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="m">7&lt;/span> passing &lt;span class="o">(&lt;/span>8ms&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;blockquote>
&lt;p>The full source code and examples are available at: &lt;a href="https://github.com/khtdr/treeify-paths">khtdr/treeify-paths&lt;/a>&lt;/p>
&lt;/blockquote>
]]></content:encoded></item><item><title>react-zondicons</title><description> A dependency-free, small, fast, good-looking React SVG icon set.
See: http://khtdr.com/react-zondicons/ for installation, usage, documentation, and examples.
Source Code at https://github.com/khtdr/react-zondicons</description><link>https://khtdr.com/react-zondicons.html</link><guid>https://khtdr.com/react-zondicons.html</guid><pubDate>Fri, 14 Aug 2020 17:17:45 -0600</pubDate><category>Software</category><content:encoded>
&lt;![CDATA[
&lt;blockquote>
&lt;p>A dependency-free, small, fast, good-looking React SVG icon set.&lt;/p>
&lt;/blockquote>
&lt;p>
See: &lt;a href="http://khtdr.com/react-zondicons/">http://khtdr.com/react-zondicons/&lt;/a> for installation, usage, documentation, and examples.&lt;/p>
&lt;p>
Source Code at &lt;a href="https://github.com/khtdr/react-zondicons">https://github.com/khtdr/react-zondicons&lt;/a>&lt;/p>
]]></content:encoded></item><item><title>Simple live-reloading Nodejs web server</title><description> Building your own live-reloading web server Follow along and build your own automatically-refreshing web server, as shown here: This setup assumes you know and use Node and NPM You are editing HTML, CSS, and Javascript by hand, because you like it. You've had some of that hot-reloading goodness before, and you want it now, too.
You don't feel like spending the weekend reading Webpack docs, so you decide that it should only take a few dozen lines of Javascript, at most, to roll your own.</description><link>https://khtdr.com/simple-live-reload-server.html</link><guid>https://khtdr.com/simple-live-reload-server.html</guid><pubDate>Fri, 01 Jan 2016 00:00:00 +0000</pubDate><category>Tutorials</category><content:encoded>
&lt;![CDATA[
&lt;div id="outline-container-headline-1" class="outline-2">
&lt;h2 id="headline-1">
Building your own live-reloading web server
&lt;/h2>
&lt;div id="outline-text-headline-1" class="outline-text-2">
&lt;p>Follow along and build your own automatically-refreshing web server, as shown here: &lt;img src="./img/preview.gif" alt="./img/preview.gif" title="./img/preview.gif" />&lt;/p>
&lt;/div>
&lt;/div>
&lt;div id="outline-container-headline-2" class="outline-2">
&lt;h2 id="headline-2">
This setup assumes you know and use Node and NPM
&lt;/h2>
&lt;div id="outline-text-headline-2" class="outline-text-2">
&lt;p>You are editing HTML, CSS, and Javascript by hand, because you like it. You&amp;#39;ve had some of that hot-reloading goodness before, and you want it now, too.&lt;/p>
&lt;p>
You don&amp;#39;t feel like spending the weekend reading Webpack docs, so you decide that it should only take a few dozen lines of Javascript, at most, to roll your own.&lt;/p>
&lt;p>
You already have node and npm installed. So you go for it.&lt;/p>
&lt;/div>
&lt;/div>
&lt;div id="outline-container-headline-3" class="outline-2">
&lt;h2 id="headline-3">
Planning a solution
&lt;/h2>
&lt;div id="outline-text-headline-3" class="outline-text-2">
&lt;p>
You will want to be able to:&lt;/p>
&lt;ul>
&lt;li>serve static files&lt;/li>
&lt;li>refresh the page whenever a file changes&lt;/li>
&lt;/ul>
&lt;p>For serving static files, there are many options to choose. The best choice will be the one that allows you to solve the &amp;#34;refresh&amp;#34; problem easiest.&lt;/p>
&lt;p>
But how can you &lt;strong>refresh the page when a file changes&lt;/strong>? Your browser will not have direct access to the files you are editing, so it will rely on a smart web-server that has access to your file system.&lt;/p>
&lt;p>
You will need to:&lt;/p>
&lt;ol>
&lt;li>detect when a file changes&lt;/li>
&lt;li>send a signal from the server to the web browser&lt;/li>
&lt;li>trigger a refresh on the page&lt;/li>
&lt;/ol>
&lt;p>Simple enough :)&lt;/p>
&lt;/div>
&lt;/div>
&lt;div id="outline-container-headline-4" class="outline-2">
&lt;h2 id="headline-4">
Putting the solution together
&lt;/h2>
&lt;div id="outline-text-headline-4" class="outline-text-2">
&lt;div id="outline-container-headline-5" class="outline-4">
&lt;h4 id="headline-5">
Building the web server
&lt;/h4>
&lt;div id="outline-text-headline-5" class="outline-text-4">
&lt;p>
&lt;a href="https://expressjs.com/">Express.js&lt;/a> has a built-in solution for serving static files. And Node.js already has the http server. Start by creating a project directory and installing the first dependency.&lt;/p>
&lt;div class="src src-bash">
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">mkdir ./live-reload-server
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">cd&lt;/span> ./live-reload-server
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">npm init -y
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">npm install express&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/div>
&lt;p>
This HTTP server will listen on port 8080 and serves files found in the same directory.&lt;/p>
&lt;div class="src src-javascript">
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="kd">var&lt;/span> &lt;span class="nx">express&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">require&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;express&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">var&lt;/span> &lt;span class="nx">app&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">express&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">app&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">use&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">express&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="kr">static&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">__dirname&lt;/span>&lt;span class="p">));&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">var&lt;/span> &lt;span class="nx">http&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">require&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;http&amp;#39;&lt;/span>&lt;span class="p">).&lt;/span>&lt;span class="nx">Server&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">app&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">http&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">listen&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">8080&lt;/span>&lt;span class="p">);&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/div>
&lt;p>
Save the code above to a file named &lt;code class="verbatim">./server.js&lt;/code> and run it:&lt;/p>
&lt;div class="src src-bash">
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">node server.js&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/div>
&lt;p>
You can verify it is working by opening a browser and going to &lt;a href="https://localhost:8080/server.js.">https://localhost:8080/server.js.&lt;/a> You will see your code that is running. Now, create a minimal webpage with a reference to a stylesheet.&lt;/p>
&lt;p>
Create the HTML and save it to &lt;code class="verbatim">./index.html&lt;/code>&lt;/p>
&lt;div class="src src-html">
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-html" data-lang="html">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&amp;lt;!DOCTYPE html&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">html&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">head&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">link&lt;/span> &lt;span class="na">rel&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#39;stylesheet&amp;#39;&lt;/span> &lt;span class="na">href&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#39;/theme.css&amp;#39;&lt;/span> &lt;span class="p">/&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">&amp;lt;/&lt;/span>&lt;span class="nt">head&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">body&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> Greetings!
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">&amp;lt;/&lt;/span>&lt;span class="nt">body&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;/&lt;/span>&lt;span class="nt">html&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/div>
&lt;p>
and the CSS…&lt;/p>
&lt;div class="src src-bash">
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">echo&lt;/span> &lt;span class="s2">&amp;#34;body { background-color:yellow }&amp;#34;&lt;/span> &amp;gt; ./theme.css&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/div>
&lt;p>
Make sure the server is running, and go to &lt;a href="https://localhost:8080.">https://localhost:8080.&lt;/a> You will see a yellow page with your greeting. So far, so good!&lt;/p>
&lt;/div>
&lt;/div>
&lt;div id="outline-container-headline-6" class="outline-4">
&lt;h4 id="headline-6">
Implementing the &amp;#34;live-reload&amp;#34; feature
&lt;/h4>
&lt;div id="outline-text-headline-6" class="outline-text-4">
&lt;p>
Node.js provides a file-watcher you can use to monitor the directory for changes. But the docs also have something to say about using this feature.&lt;/p>
&lt;blockquote>
&lt;p>The fs.watch API is not 100% consistent across platforms, and is unavailable in some situations.&lt;/p>
&lt;p>
The recursive option is only supported on OS X and Windows.&lt;/p>
&lt;/blockquote>
&lt;p>
Luckily(?) for you, this is good enough to get started. You will still need to signal to the browser when a change is detected, and for that you can use &lt;a href="https://socket.io/">Socket.io&lt;/a>.&lt;/p>
&lt;div class="src src-bash">
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">npm install socket.io socket.io-client&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/div>
&lt;p>
The code is straight forward: watch the working directory for changes and emit an event with Socket.io.&lt;/p>
&lt;div class="src src-javascript">
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="kd">var&lt;/span> &lt;span class="nx">fs&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">require&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;fs&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">var&lt;/span> &lt;span class="nx">io&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">require&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;socket.io&amp;#39;&lt;/span>&lt;span class="p">)(&lt;/span>&lt;span class="nx">http&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">fs&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">watch&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">__dirname&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">recursive&lt;/span>&lt;span class="o">:&lt;/span>&lt;span class="kc">true&lt;/span> &lt;span class="p">},&lt;/span> &lt;span class="kd">function&lt;/span> &lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">io&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">emit&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;file-change-event&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">});&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/div>
&lt;p>
The Socket.io server can be started various ways. Here it is given the HTTP server from the previous step.&lt;/p>
&lt;p>
Finally, a puzzle to solve. Something needs to listen for the &lt;code class="verbatim">file-change-event&lt;/code> emitted by the server. Upon receiving the event, the page also needs refreshed. So it makes sense to put the &amp;#34;listening code&amp;#34; on the webpage itself.&lt;/p>
&lt;p>
For obviously obvious reasons, you don&amp;#39;t want to add the javascript to &lt;em>every page you fiddle with&lt;/em>. Better to have the server inject it automatically for you!&lt;/p>
&lt;p>
So what is this &amp;#34;listening code&amp;#34; that needs to be on every HTML page?&lt;/p>
&lt;div class="src src-html">
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-html" data-lang="html">&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">script&lt;/span> &lt;span class="na">src&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;/node_modules/socket.io-client/dist/socket.io.js&amp;#34;&lt;/span>&lt;span class="p">&amp;gt;&amp;lt;/&lt;/span>&lt;span class="nt">script&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">script&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">var&lt;/span> &lt;span class="nx">socket&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">io&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">socket&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">on&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;file-change-event&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kd">function&lt;/span> &lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">window&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">location&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">reload&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;/&lt;/span>&lt;span class="nt">script&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/div>
&lt;p>
The snippet above includes the client library that we installed with NPM earlier. It creates a new Socket.io client, and upon receiving the &lt;code class="verbatim">file-change-event&lt;/code> from the server, reloads the page.&lt;/p>
&lt;p>
Now you need to serve that snippet of javascript along with every HTML page. Back to Express.&lt;/p>
&lt;p>
Write a &lt;code class="verbatim">GET&lt;/code> handler that intercepts requests for HTML pages and appends the &amp;#34;listening code&amp;#34; to the page.&lt;/p>
&lt;div class="src src-html">
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-html" data-lang="html">&lt;span class="line">&lt;span class="cl">app.get(&amp;#39;/index.html&amp;#39;, function (_, res) {
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> fs.readFile(__dirname + &amp;#39;/index.html&amp;#39;, function (_, data) {
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> res.send(data
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> + &amp;#39;&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">script&lt;/span> &lt;span class="na">src&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;/node_modules/socket.io-client/dist/socket.io.js&amp;#34;&lt;/span>&lt;span class="p">&amp;gt;&amp;lt;/&lt;/span>&lt;span class="nt">script&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>&amp;#39;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> + &amp;#39;&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">script&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>&lt;span class="s1">&amp;#39;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1"> + &amp;#39;&lt;/span> &lt;span class="kd">var&lt;/span> &lt;span class="nx">socket&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">io&lt;/span>&lt;span class="p">();&lt;/span>&lt;span class="s1">&amp;#39;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1"> + &amp;#39;&lt;/span> &lt;span class="nx">socket&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">on&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;file-change-event&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kd">function&lt;/span> &lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="s1">&amp;#39;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1"> + &amp;#39;&lt;/span> &lt;span class="nb">window&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">location&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">reload&lt;/span>&lt;span class="p">();&lt;/span>&lt;span class="s1">&amp;#39;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1"> + &amp;#39;&lt;/span> &lt;span class="p">});&lt;/span>&lt;span class="s1">&amp;#39;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1"> + &amp;#39;&lt;/span>&lt;span class="p">&amp;lt;/&lt;/span>&lt;span class="nt">script&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>&amp;#39;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> );
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> });
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">});&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/div>
&lt;p>
That solves the problem for the &lt;code class="verbatim">index.html&lt;/code> page, but what about the rest of the HTML pages? Instead of hard-coding the path, you can use a regular expression to intercept requests for HTML pages and directories.&lt;/p>
&lt;p>
When a request ends in a slash, take care to append &lt;code class="verbatim">index.html&lt;/code> to the requested path.&lt;/p>
&lt;p>
Change:&lt;/p>
&lt;div class="src src-javascript">
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">app&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;/index.html&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kd">function&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">_&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">res&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">fs&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">readFile&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">__dirname&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="s1">&amp;#39;/index.html&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kd">function&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">_&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">data&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">//...
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">});&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/div>
&lt;p>
to:&lt;/p>
&lt;div class="src src-javascript">
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">app&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">get&lt;/span>&lt;span class="p">([&lt;/span>&lt;span class="sr">/\/$/&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="sr">/.*\.html$/&lt;/span>&lt;span class="p">],&lt;/span> &lt;span class="kd">function&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">req&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">res&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">var&lt;/span> &lt;span class="nx">filename&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">__dirname&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nx">req&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">path&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">filename&lt;/span> &lt;span class="o">+=&lt;/span> &lt;span class="nx">filename&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">endsWith&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;/&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">?&lt;/span> &lt;span class="s1">&amp;#39;index.html&amp;#39;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;&amp;#39;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">fs&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">readFile&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">filename&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kd">function&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">_&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">data&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">//...
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">});&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/div>
&lt;/div>
&lt;/div>
&lt;/div>
&lt;/div>
&lt;div id="outline-container-headline-7" class="outline-2">
&lt;h2 id="headline-7">
Final result, copy+paste and start hacking
&lt;/h2>
&lt;div id="outline-text-headline-7" class="outline-text-2">
&lt;p>Now, &lt;strong>putting it all together!&lt;/strong>&lt;/p>
&lt;div class="src src-javascript">
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="kd">var&lt;/span> &lt;span class="nx">express&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">require&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;express&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">var&lt;/span> &lt;span class="nx">app&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">express&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">app&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">get&lt;/span>&lt;span class="p">([&lt;/span>&lt;span class="sr">/\/$/&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="sr">/.*\.html$/&lt;/span>&lt;span class="p">],&lt;/span> &lt;span class="kd">function&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">req&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">res&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">var&lt;/span> &lt;span class="nx">filename&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">__dirname&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nx">req&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">path&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">filename&lt;/span> &lt;span class="o">+=&lt;/span> &lt;span class="nx">filename&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">endsWith&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;/&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">?&lt;/span> &lt;span class="s1">&amp;#39;index.html&amp;#39;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;&amp;#39;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">fs&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">readFile&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">filename&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kd">function&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">_&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">data&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">res&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">send&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">data&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">+&lt;/span> &lt;span class="s1">&amp;#39;&amp;amp;lt;script src=&amp;#34;/node_modules/socket.io-client/dist/socket.io.js&amp;#34;&amp;amp;gt;&amp;amp;lt;/script&amp;amp;gt;&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">+&lt;/span> &lt;span class="s1">&amp;#39;&amp;amp;lt;script&amp;amp;gt;&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">+&lt;/span> &lt;span class="s1">&amp;#39; var socket = io();&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">+&lt;/span> &lt;span class="s1">&amp;#39; socket.on(&amp;#34;file-change-event&amp;#34;, function () {&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">+&lt;/span> &lt;span class="s1">&amp;#39; window.location.reload();&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">+&lt;/span> &lt;span class="s1">&amp;#39; });&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">+&lt;/span> &lt;span class="s1">&amp;#39;&amp;amp;lt;/script&amp;amp;gt;&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">app&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">use&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">express&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="kr">static&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">__dirname&lt;/span>&lt;span class="p">));&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">var&lt;/span> &lt;span class="nx">http&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">require&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;http&amp;#39;&lt;/span>&lt;span class="p">).&lt;/span>&lt;span class="nx">Server&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">app&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">http&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">listen&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">8080&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">var&lt;/span> &lt;span class="nx">fs&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">require&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;fs&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">var&lt;/span> &lt;span class="nx">io&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">require&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;socket.io&amp;#39;&lt;/span>&lt;span class="p">)(&lt;/span>&lt;span class="nx">http&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">fs&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">watch&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">__dirname&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">recursive&lt;/span>&lt;span class="o">:&lt;/span>&lt;span class="kc">true&lt;/span> &lt;span class="p">},&lt;/span> &lt;span class="kd">function&lt;/span> &lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">io&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">emit&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;file-change-event&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">});&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/div>
&lt;p>
&lt;em>That&amp;#39;s it!&lt;/em>&lt;/p>
&lt;p>
Start the server with &lt;code class="verbatim">node server.js&lt;/code>, go to &lt;a href="https://localhost:8080">https://localhost:8080&lt;/a> in your browser, and take a good look at your yellow page. Open up the css file you created earlier, and change &lt;code class="verbatim">yellow&lt;/code> to &lt;code class="verbatim">orange&lt;/code>. Save, &lt;em>but don&amp;#39;t refresh your page&lt;/em>. Just observe. The page will automatically update.&lt;/p>
&lt;blockquote>
&lt;p>The files in this tutorial can be found at:&lt;/p>
&lt;p>
&lt;a href="https://github.com/khtdr/live-reload-web-server">github.com/khtdr/live-reload-web-server&lt;/a>&lt;/p>
&lt;/blockquote>
&lt;/div>
&lt;/div>
]]></content:encoded></item></channel></rss>