<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Samuel Fontebasso</title>
    <description>The latest articles on DEV Community by Samuel Fontebasso (@fontebasso).</description>
    <link>https://dev.to/fontebasso</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3120954%2Fafcdb873-5012-4aef-ab6d-58d282f7748d.jpeg</url>
      <title>DEV Community: Samuel Fontebasso</title>
      <link>https://dev.to/fontebasso</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/fontebasso"/>
    <language>en</language>
    <item>
      <title>Validate Your Env at Build Time — with Custom Rules Powered by Amazon Q Developer</title>
      <dc:creator>Samuel Fontebasso</dc:creator>
      <pubDate>Sun, 11 May 2025 22:21:22 +0000</pubDate>
      <link>https://dev.to/fontebasso/validate-your-env-at-build-time-with-custom-rules-powered-by-amazon-q-developer-5b3h</link>
      <guid>https://dev.to/fontebasso/validate-your-env-at-build-time-with-custom-rules-powered-by-amazon-q-developer-5b3h</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/aws-amazon-q-v2025-04-30"&gt;Amazon Q Developer "Quack The Code" Challenge&lt;/a&gt;: Crushing the Command Line&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;I created &lt;code&gt;envguardr&lt;/code&gt;, a CLI tool that validates environment variables at build time. It’s useful for projects where &lt;code&gt;.env&lt;/code&gt; files or runtime checks aren't enough. It handles types, required fields, and default values, but I felt it needed more flexibility.&lt;/p&gt;

&lt;p&gt;To address that, I enhanced the underlying validation package &lt;code&gt;valitype&lt;/code&gt; by adding support for custom validators. This was one of the ideas suggested by Amazon Q Developer during the challenge. That single improvement unlocked a range of advanced use cases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step-by-step
&lt;/h3&gt;

&lt;p&gt;Install envguardr globally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; envguardr
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create an &lt;code&gt;env.schema.js&lt;/code&gt; file with custom validation logic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;API_KEY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;custom&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;validator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="sr"&gt;/^&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;a-z0-9&lt;/span&gt;&lt;span class="se"&gt;]{16}&lt;/span&gt;&lt;span class="sr"&gt;$/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;errorMessage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;API_KEY must be 16 alphanumeric characters&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;envguardr validate env.schema.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Terminal demo: running &lt;code&gt;envguardr&lt;/code&gt; with a custom schema validation for &lt;code&gt;API_KEY&lt;/code&gt;:
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8ium0dv0f2nw71jo0wze.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8ium0dv0f2nw71jo0wze.gif" alt="Terminal demo: running envguardr with a custom schema validation for API_KEY" width="1117" height="431"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Code Repository
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/fontebasso/valitype" rel="noopener noreferrer"&gt;https://github.com/fontebasso/valitype&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/fontebasso/envguardr" rel="noopener noreferrer"&gt;https://github.com/fontebasso/envguardr&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Used Amazon Q Developer
&lt;/h2&gt;

&lt;p&gt;This challenge was my first experience with Amazon Q Developer, and I was genuinely impressed. It’s exactly the kind of tool I always felt was missing for developers working with AI.&lt;/p&gt;

&lt;p&gt;Amazon Q Developer was able to read my codebase, understand its context, and assist in meaningful ways. It helped me improve typing, write better tests, fix subtle lint issues, and explore useful new features.&lt;/p&gt;

&lt;p&gt;From the several improvements it suggested for &lt;code&gt;valitype&lt;/code&gt;, I chose to implement custom validators. That feature alone made &lt;code&gt;envguardr&lt;/code&gt; much more powerful, giving it the flexibility needed for advanced configuration validation.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>awschallenge</category>
      <category>ai</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Stop trusting your .env file</title>
      <dc:creator>Samuel Fontebasso</dc:creator>
      <pubDate>Sat, 10 May 2025 17:30:38 +0000</pubDate>
      <link>https://dev.to/fontebasso/stop-trusting-your-env-file-493n</link>
      <guid>https://dev.to/fontebasso/stop-trusting-your-env-file-493n</guid>
      <description>&lt;p&gt;A personal take on how I stopped shipping broken Vite builds by validating environment variables before the build even starts. No JSON schema, no magic — just JavaScript and clear rules.&lt;/p&gt;

&lt;h2&gt;
  
  
  A blunt tool for a stupidly common problem
&lt;/h2&gt;

&lt;p&gt;After building more React apps with Vite than I care to admit, I noticed a recurring theme: most of the time, what broke wasn't the code — it was the environment.&lt;/p&gt;

&lt;p&gt;A missing VITE_ variable. A malformed URL. A boolean that was actually a string. A Docker ARG that never made it to the final build. And of course, the worst kind: it didn't crash the build... it crashed the user experience.&lt;/p&gt;

&lt;p&gt;I got tired of catching these bugs in staging (or worse, production), so I built a tool that would blow up my build early — on purpose.&lt;/p&gt;

&lt;p&gt;It's called envguardr, and it's dead simple.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem with Vite and environment variables
&lt;/h2&gt;

&lt;p&gt;Vite helpfully injects any variable prefixed with &lt;code&gt;VITE_&lt;/code&gt; into &lt;code&gt;import.meta.env&lt;/code&gt;, but:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It doesn't check if the variable is actually defined.&lt;/li&gt;
&lt;li&gt;It doesn't validate types.&lt;/li&gt;
&lt;li&gt;It assumes everything is a string, and that's your problem now.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can write &lt;code&gt;if (VITE_ENABLE_FEATURE)&lt;/code&gt; and end up with true, "true", "banana", or undefined — and Vite will happily compile it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I use now (and why it finally works)
&lt;/h2&gt;

&lt;p&gt;My stack: React + Vite frontend, Nginx for static serving, Docker multistage for builds. Nothing exotic. What changed was the discipline — and the tooling.&lt;/p&gt;

&lt;p&gt;Here’s how I validate my environment before anything gets built:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// env.schema.js&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;VITE_API_URL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;url&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;VITE_APP_VERSION&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;VITE_APP_ENV&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;enum&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;staging&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;production&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;production&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; 
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s it. No YAML, no JSON schema. Just JavaScript and some rules that make sense.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Dockerfile
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;node:18&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;builder&lt;/span&gt;

&lt;span class="k"&gt;ARG&lt;/span&gt;&lt;span class="s"&gt; VITE_API_URL&lt;/span&gt;
&lt;span class="k"&gt;ARG&lt;/span&gt;&lt;span class="s"&gt; VITE_APP_VERSION&lt;/span&gt;
&lt;span class="k"&gt;ARG&lt;/span&gt;&lt;span class="s"&gt; VITE_APP_ENV&lt;/span&gt;

&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; VITE_API_URL=$VITE_API_URL&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; VITE_APP_VERSION=$VITE_APP_VERSION&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; VITE_APP_ENV=$VITE_APP_ENV&lt;/span&gt;

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;npm ci
&lt;span class="k"&gt;RUN &lt;/span&gt;npx envguardr validate ./env.schema.js
&lt;span class="k"&gt;RUN &lt;/span&gt;npm run build

&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; nginx:alpine&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=builder /app/dist /usr/share/nginx/html&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Validation happens before the build. If anything’s missing or wrong, it fails fast — as it should.&lt;/p&gt;

&lt;h2&gt;
  
  
  What changed
&lt;/h2&gt;

&lt;p&gt;Since I added &lt;code&gt;envguardr&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I haven’t shipped a broken build.&lt;/li&gt;
&lt;li&gt;I don’t debug missing env vars in production anymore.&lt;/li&gt;
&lt;li&gt;My CI logs finally tell me what’s wrong instead of silently succeeding.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No magic. Just boundaries.&lt;/p&gt;

&lt;h2&gt;
  
  
  For anyone who's ever dealt with process.env in Docker
&lt;/h2&gt;

&lt;p&gt;This isn't another generic linter. It's a purpose-built CLI for one thing: making sure your environment is what your app actually needs.&lt;/p&gt;

&lt;p&gt;You write a schema. You run &lt;code&gt;envguardr&lt;/code&gt;. It validates your env. If something's wrong, it kills the build.&lt;/p&gt;

&lt;p&gt;That's the whole point.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; envguardr
npx envguardr validate ./env.schema.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;I built &lt;code&gt;envguardr&lt;/code&gt; to protect myself from careless builds. It just happens to work for other people too.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>devops</category>
      <category>docker</category>
      <category>vite</category>
      <category>react</category>
    </item>
  </channel>
</rss>
