<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Ryuya</title>
    <description>The latest articles on Forem by Ryuya (@ryuya).</description>
    <link>https://forem.com/ryuya</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%2F573247%2F1003e13a-ce59-439d-a392-f6f1d216aa5f.jpg</url>
      <title>Forem: Ryuya</title>
      <link>https://forem.com/ryuya</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/ryuya"/>
    <language>en</language>
    <item>
      <title>Bringing Baseline into Product Development — and Keeping It Safe in Practice</title>
      <dc:creator>Ryuya</dc:creator>
      <pubDate>Wed, 10 Sep 2025 04:10:25 +0000</pubDate>
      <link>https://forem.com/ryuya/bringing-baseline-into-product-development-and-keeping-it-safe-in-practice-3pb8</link>
      <guid>https://forem.com/ryuya/bringing-baseline-into-product-development-and-keeping-it-safe-in-practice-3pb8</guid>
      <description>&lt;p&gt;&lt;a href="https://web-platform-dx.github.io/web-features/" rel="noopener noreferrer"&gt;Baseline&lt;/a&gt; gives teams a simple way to answer a hard question: when is a web platform feature safe to use everywhere that matters? Instead of juggling browser-version matrices, you align on a shared, function-level line and make consistent, defensible decisions.&lt;/p&gt;

&lt;p&gt;There is also a clear business angle. If a user’s browser silently lacks a feature you rely on, you can lose conversions, trigger avoidable support tickets, and erode trust without anyone noticing the root cause. Treating Baseline as a product standard reduces that risk. It turns a nebulous, recurring debate into a policy you can document, audit, and enforce automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  A quick primer on Baseline
&lt;/h2&gt;

&lt;p&gt;Baseline tracks when a feature reaches parity across the four major engines (Safari, Chrome, Edge, and Firefox). It communicates readiness in three stages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Limited availability — Not yet supported in all Baseline browsers; treat as experimental and avoid for production unless you have a well‑designed fallback.&lt;br&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%2Fp2maystjc3gfzn2o6btf.png" 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%2Fp2maystjc3gfzn2o6btf.png" alt="Baseline Widely Available" width="800" height="101"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Newly available — Supported in all current stable releases; good default for early adoption with care.&lt;br&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%2Fiy0t1vje49ku8f3ic344.png" 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%2Fiy0t1vje49ku8f3ic344.png" alt="Baseline Newly available" width="800" height="116"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Widely available — Newly, plus 30 months of universal support; practical proxy for very low risk in the wild.&lt;br&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%2Frrbsyttq4xxr6q0b6poq.png" 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%2Frrbsyttq4xxr6q0b6poq.png" alt=" " width="800" height="113"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can also target by year. For example, “2023” means: allow anything that became Baseline newly available in 2023 or earlier.&lt;/p&gt;

&lt;p&gt;It is a feature‑first lens. Rather than anchoring on version lists for each browser, you ask, “Has this capability reached the line?” and get a single answer you can reason about.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choosing “our Baseline”
&lt;/h2&gt;

&lt;p&gt;Start with Widely as the default. It’s a conservative, low‑friction starting point because it bakes in real‑world adoption time after universal support lands.&lt;/p&gt;

&lt;p&gt;Then estimate “our Year.” Use your analytics or RUM to understand the browsers your users actually run. Vary the year (2021, 2022, 2023, …) and estimate coverage. If you use Google Analytics, &lt;a href="https://chrome.dev/google-analytics-baseline-checker/" rel="noopener noreferrer"&gt;the Google Analytics Baseline Checker&lt;/a&gt; can visualize this; otherwise, you can massage internal logs into the same shape.&lt;/p&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%2F25wxccpx641szuq72aob.png" 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%2F25wxccpx641szuq72aob.png" alt=" " width="800" height="677"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, define your exception policy. Some features come with reasonable fallbacks you can ship today and progressively enhance later. Others carry more cross-browser risk and should wait even if they are technically Widely. Write down how exceptions are proposed, reviewed, and documented.&lt;/p&gt;

&lt;p&gt;This sequence—safe default, data-informed tuning, explicit exceptions—makes the policy clear and keeps decisions explainable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why not rely on UA tables alone?
&lt;/h2&gt;

&lt;p&gt;User-Agent strings are easy to spoof and often polluted by crawlers and scanners. Even when they are accurate, a version label does not capture enterprise policies, flags, or safety modes that can disable capabilities. UA-led policies also force you to manage version matrices, which age poorly and rarely map cleanly to how specifications group features.&lt;/p&gt;

&lt;p&gt;Baseline draws the line at the capability itself. Keep UA data for coverage estimates and stakeholder communication, but let features drive the decision.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bringing it into the workflow
&lt;/h2&gt;

&lt;p&gt;First, set your build/transpile targets to align with your chosen Baseline. Some tools default to Widely already; others let you convert Baseline to a Browserslist query or an esbuild target. The goal is that the code you ship matches the line you agreed on.&lt;/p&gt;

&lt;p&gt;Second, catch issues where they happen: in the editor and in CI. ESLint can enforce Baseline for JavaScript, and complementary plugins can do the same for CSS and HTML. When someone reaches for a feature that sits beyond the line, they see a precise, actionable message before it merges.&lt;/p&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%2F360cp83ysrlsnvfshusy.png" 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%2F360cp83ysrlsnvfshusy.png" alt=" " width="800" height="48"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Third, document the policy. State the default (for example, “Widely”), the way you set the year, and how exceptions work. That turns a tribal norm into policy-as-code and keeps newcomers aligned.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Example&lt;/strong&gt;: don’t use &lt;code&gt;Date#getYear()/setYear()&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getYear" rel="noopener noreferrer"&gt;&lt;code&gt;Date#getYear()&lt;/code&gt;&lt;/a&gt; and &lt;code&gt;Date#setYear()&lt;/code&gt; are deprecated. They also fall below a sensible Baseline threshold. Reaching for them is a recipe for subtle bugs.&lt;/p&gt;

&lt;p&gt;With a Baseline rule enabled, you would see a message like:&lt;/p&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%2Fz8eykcopqq20qupyqsyo.png" 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%2Fz8eykcopqq20qupyqsyo.png" alt=" " width="800" height="159"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  One policy, three surfaces: JS, CSS, and HTML
&lt;/h2&gt;

&lt;p&gt;The easiest way to make Baseline “real” for your team is to enable it where code is written. JavaScript is the obvious starting point, but it helps to bring CSS and HTML into the same conversation so your policy feels coherent.&lt;/p&gt;

&lt;p&gt;Here is a Flat Config example that wires the three together. Adjust the file globs and the strictness to match your repo. The JavaScript section uses the built‑in presets exposed by &lt;code&gt;eslint-plugin-baseline-js&lt;/code&gt;.&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;// eslint.config.js (Flat Config)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;tsParser&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@typescript-eslint/parser&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;baselineJs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;BASELINE&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;eslint-plugin-baseline-js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;cssPlugin&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@eslint/css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;htmlPlugin&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@html-eslint/eslint-plugin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;htmlParser&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@html-eslint/parser&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&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="c1"&gt;// Register the JS plugin once&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;baseline-js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;baselineJs&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;

  &lt;span class="c1"&gt;// JavaScript (JS) — recommended preset (auto Web APIs + JS builtins)&lt;/span&gt;
  &lt;span class="nx"&gt;baselineJs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;configs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;recommended&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;available&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;BASELINE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;WIDELY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;level&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;warn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;

  &lt;span class="c1"&gt;// TypeScript (TS) — attach parser + type-aware preset&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;files&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;**/*.{ts,tsx}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;languageOptions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;tsParser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;parserOptions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;project&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./tsconfig.json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nx"&gt;baselineJs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;configs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;recommended-ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]({&lt;/span&gt; &lt;span class="na"&gt;available&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;BASELINE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;WIDELY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;level&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;warn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;

  &lt;span class="c1"&gt;// CSS: Baseline&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;files&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;**/*.{css,scss}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;cssPlugin&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;language&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@css/css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@css/use-baseline&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;warn&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;available&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;widely&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;

  &lt;span class="c1"&gt;// HTML: Baseline&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;files&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;**/*.{html,htm}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@html-eslint&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;htmlPlugin&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;languageOptions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;htmlParser&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@html-eslint/use-baseline&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;warn&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;available&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;widely&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;JS: &lt;a href="https://github.com/3ru/eslint-plugin-baseline-js" rel="noopener noreferrer"&gt;&lt;code&gt;eslint-plugin-baseline-js&lt;/code&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;CSS: &lt;a href="https://github.com/eslint/css" rel="noopener noreferrer"&gt;&lt;code&gt;@eslint/css&lt;/code&gt;&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;HTML: &lt;a href="https://github.com/yeonjuan/html-eslint" rel="noopener noreferrer"&gt;&lt;code&gt;@html-eslint/eslint-plugin&lt;/code&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Notes&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can target a specific year (e.g., &lt;code&gt;{ available: 2022 }&lt;/code&gt;). Items with “Limited availability” are treated as beyond the configured year, so they will be flagged until they enter Baseline.&lt;/li&gt;
&lt;li&gt;The single rule is &lt;code&gt;baseline-js/use-baseline&lt;/code&gt;. Presets above expand it for JS and TS with sensible defaults (auto for JS, type‑aware for TS).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Closing thought
&lt;/h2&gt;

&lt;p&gt;Baseline is a way to agree on reality. Pick a line, show your work, and let tooling hold it for you. That is how teams move fast without gambling with user experience.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>css</category>
      <category>html</category>
    </item>
    <item>
      <title>Translate Markdown to Any Language (GitHub Bot)</title>
      <dc:creator>Ryuya</dc:creator>
      <pubDate>Fri, 31 Mar 2023 14:38:32 +0000</pubDate>
      <link>https://forem.com/ryuya/translate-markdown-to-any-language-github-bot-3pde</link>
      <guid>https://forem.com/ryuya/translate-markdown-to-any-language-github-bot-3pde</guid>
      <description>&lt;p&gt;Most open-source projects are written in English, raising barriers to participation from speakers of other languages. In addition, translation is a labor-intensive process, so documentation has yet to be internationalized to a great extent. &lt;br&gt;
I have created a &lt;a href="https://github.com/marketplace/actions/gpt-translate" rel="noopener noreferrer"&gt;GitHub Actions&lt;/a&gt; that automatically translate documents using multiple AI models.&lt;br&gt;
It is &lt;a href="https://github.com/3ru/gpt-translate" rel="noopener noreferrer"&gt;open source&lt;/a&gt; and requires an individual API key, but it is free.&lt;/p&gt;


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

&lt;p&gt;All you need is an Open AI API Key and Actions workflow settings. Please see &lt;a href="https://github.com/3ru/gpt-translate#readme" rel="noopener noreferrer"&gt;README &lt;/a&gt;for details.&lt;/p&gt;

&lt;p&gt;To prevent your API KEY from being misused, we only allow people who have write permission to access the repository to run the bot.&lt;/p&gt;
&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;p&gt;Once the workflow is set up, comment on the issue or pr with a command to translate the input file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/gpt-translate &lt;span class="o"&gt;[&lt;/span&gt;input filepath] &lt;span class="o"&gt;[&lt;/span&gt;output filepath] &lt;span class="o"&gt;[&lt;/span&gt;target language] 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Comment on Issues
&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%2Frfzm2dfv8be2ahizdqgy.png" 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%2Frfzm2dfv8be2ahizdqgy.png" alt="Entering commands" width="766" height="214"&gt;&lt;/a&gt;&lt;a href="https://github.com/3ru/gpt-translate/issues/1#issuecomment-1491882236" rel="noopener noreferrer"&gt;View Actual Issues&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Auto-generated PR
&lt;/h3&gt;

&lt;p&gt;A PR is created depending on where the command is entered. (If you comment on a PR, the commit is added to that PR.)&lt;/p&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%2F3rfay4lq60nfn0rczhyo.png" 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%2F3rfay4lq60nfn0rczhyo.png" alt="Auto-generated PR" width="800" height="671"&gt;&lt;/a&gt;&lt;a href="https://github.com/3ru/gpt-translate/pull/4" rel="noopener noreferrer"&gt;View actual PR&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Interestingly, I could translate Voynich's Manuscript (undeciphered script), ancient Greek, and other languages. (Not possible with GPT-4)&lt;br&gt;
We could also build a kind of OSS document for time travelers :)&lt;/p&gt;
&lt;h2&gt;
  
  
  Human-in-the-Loop
&lt;/h2&gt;

&lt;p&gt;Originally, the texts translated by GPT are of fairly high quality.&lt;/p&gt;

&lt;p&gt;However, a human can also review the translation files created by this bot to perfect the translation further.&lt;/p&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%2F9xx41cfhlg83cnmd9rmc.png" 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%2F9xx41cfhlg83cnmd9rmc.png" alt="PR review" width="800" height="527"&gt;&lt;/a&gt;&lt;br&gt;
GitHub's function to accept reviews as is on a new commit allows us to build a very seamless translation experience.&lt;/p&gt;



&lt;p&gt;If you have any suggestions for improvement or bugs, please feel free to write them in Issues!&lt;/p&gt;

&lt;p&gt;🌎As a non-English speaking person, I would be happy if the various OSS are easier to understand!&lt;/p&gt;


&lt;h3&gt;
  
  
  Repo
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Thanks for the 250 stars🌟&lt;/strong&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/3ru" rel="noopener noreferrer"&gt;
        3ru
      &lt;/a&gt; / &lt;a href="https://github.com/3ru/gpt-translate" rel="noopener noreferrer"&gt;
        gpt-translate
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      💬Translate Files into Any Languages with AI
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;🌎 Markdown Translation BOT&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="https://codeclimate.com/github/3ru/gpt-translate/maintainability" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/7a6a2cac4cbbda169779eaf17ae8c0f07019ba236994d27c6c22cfc5b96462ee/68747470733a2f2f6170692e636f6465636c696d6174652e636f6d2f76312f6261646765732f61313365613466333739313362613662613537302f6d61696e7461696e6162696c697479" alt="Maintainability"&gt;&lt;/a&gt;
&lt;a href="https://github.com/3ru/gpt-translate/actions/workflows/gpt-translate.yml" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/3ru/gpt-translate/actions/workflows/gpt-translate.yml/badge.svg" alt="GPT Translate"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://openai.com/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/b292c9035a9da83abd5831f7265a556baf77439a50b26c6bb94f460a227dbf87/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f2d4f70656e41492d77686974653f7374796c653d666c61742d737175617265266c6f676f3d6f70656e6169266c6f676f436f6c6f723d626c61636b" alt="OpenAI"&gt;&lt;/a&gt;
&lt;a href="https://azure.microsoft.com/en-us/products/ai-services/openai-service" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/023b8e20c9624a5b9526ace98fe127e2c54c22684cd2b688f2831f33f94e45ff/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f2d4d6963726f736f6674253230417a7572652d77686974653f7374796c653d666c61742d737175617265266c6f676f3d6d6963726f736f6674617a75726526636f6c6f723d303037384434" alt="Azure"&gt;&lt;/a&gt;
&lt;a href="https://www.anthropic.com/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/12d48d8b5d741d39e5d760d461e8615dc3d89a062d47ba18cba30b9487c37024/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f2d416e7468726f7069632d626c61636b3f7374796c653d666c61742d737175617265266c6f676f3d616e7468726f706963266c6f676f436f6c6f723d626c61636b26636f6c6f723d643461323766" alt="Anthropic"&gt;&lt;/a&gt;
&lt;a href="https://docs.perplexity.ai/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/57b3a3db0eda24f227c258c8e7afb121dc16db0a33ba103e894106eba0998ee2/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f2d506572706c65786974792d626c61636b3f7374796c653d666c61742d737175617265266c6f676f3d706572706c657869747926636f6c6f723d626c61636b" alt="Perplexity"&gt;&lt;/a&gt;
&lt;a href="https://ai.google/discover/generativeai/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/bd2f3e359180d923763d500ca33b95728f9a99787a967a1e4451e3c01255e3b1/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f2d476f6f676c6525323067656d696e692d77686974653f7374796c653d666c61742d737175617265266c6f676f3d676f6f676c6567656d696e6926636f6c6f723d7768697465" alt="Google"&gt;&lt;/a&gt;
&lt;a href="https://groq.com/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/1f8315db33892df038dd753df477d7b1c0e400dfc5a4d779962ae5bc039f6417/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f2d47726f712d626c61636b3f7374796c653d666c61742d737175617265266c6f676f436f6c6f723d626c61636b26636f6c6f723d463535303336" alt="Groq"&gt;&lt;/a&gt;
&lt;a href="https://fireworks.ai/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/038894100790666d76cf372c24acb31b8a5aa67bb42372f531efb573716b459a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f2d46697265776f726b7325323041492d626c61636b3f7374796c653d666c61742d73717561726526636f6c6f723d363331666565" alt="Fireworks"&gt;&lt;/a&gt;
&lt;a href="https://mistral.ai/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/9c6b4d008686ef97218568669b752d8f7fe165482fbf4dc6ac2be4f1d5eac006/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f2d4d69737472616c25323041492d626c61636b3f7374796c653d666c61742d73717561726526636f6c6f723d666637303030" alt="Mistral"&gt;&lt;/a&gt;
&lt;a href="https://cohere.com/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/1a9a637fb2a4c1f0632924cdcf394eb919467c5c6fdda01aab13aac9f4dda8bd/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f2d436f686572652d626c61636b3f7374796c653d666c61742d73717561726526636f6c6f723d333935393463" alt="Cohere"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/README.md" rel="noopener noreferrer"&gt;English&lt;/a&gt; |
&lt;a href="https://github.com/README/README.zh-CN.md" rel="noopener noreferrer"&gt;简体中文&lt;/a&gt; |
&lt;a href="https://github.com/README/README.zh-TW.md" rel="noopener noreferrer"&gt;繁體中文&lt;/a&gt; |
&lt;a href="https://github.com/README/README.es.md" rel="noopener noreferrer"&gt;Español&lt;/a&gt; |
&lt;a href="https://github.com/README/README.hi.md" rel="noopener noreferrer"&gt;हिंदी, हिन्दी&lt;/a&gt; |
&lt;a href="https://github.com/README/README.ko.md" rel="noopener noreferrer"&gt;한국어&lt;/a&gt; |
&lt;a href="https://github.com/README/README.ja.md" rel="noopener noreferrer"&gt;日本語&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This GitHub action translates your markdown files into multiple languages using multiple AI models.&lt;/p&gt;
&lt;div class="markdown-alert markdown-alert-tip"&gt;
&lt;p class="markdown-alert-title"&gt;Tip&lt;/p&gt;
&lt;p&gt;Now Available: &lt;strong&gt;AI Models from Multiple Providers✨&lt;/strong&gt;  &lt;br&gt;
We've expanded beyond OpenAI to support various AI model providers.  &lt;br&gt;
For a comprehensive &lt;a href="https://g-t.vercel.app/docs/references/supported-model-provider" rel="nofollow noopener noreferrer"&gt;list of supported providers&lt;/a&gt; and detailed information, please refer to our &lt;a href="https://github.com/3ru/gpt-translate/releases/tag/v1.2.0-beta" rel="noopener noreferrer"&gt;release notes&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;br&gt;
🧐 Current Status


&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The action supports translating &lt;strong&gt;markdown(&lt;code&gt;.md&lt;/code&gt;), markdown-jsx(&lt;code&gt;.mdx&lt;/code&gt;), json(&lt;code&gt;.json&lt;/code&gt;) files only&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The command can be executed exclusively by individuals with &lt;strong&gt;write permissions to the repository&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These limitations prevent API abuse by non-trusted parties.&lt;/p&gt;



&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🔧 Setup&lt;/h2&gt;

&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Repository Settings&lt;/h3&gt;

&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h4 class="heading-element"&gt;1. Settings &amp;gt; Actions &amp;gt; General&lt;/h4&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Enable &lt;code&gt;Read and write permissions&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Enable &lt;code&gt;Allow GitHub Actions to create and approve pull requests&lt;/code&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/69892552/228692074-d8d009a8-9272-4023-97b1-3cbc637d5d84.jpg"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F69892552%2F228692074-d8d009a8-9272-4023-97b1-3cbc637d5d84.jpg" alt="permissions"&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="markdown-heading"&gt;
&lt;h4 class="heading-element"&gt;2. Settings &amp;gt; Secrets and variables &amp;gt; Actions&lt;/h4&gt;

&lt;/div&gt;


&lt;ul&gt;

&lt;li&gt;Set &lt;a href="https://platform.openai.com/account/api-keys" rel="nofollow noopener noreferrer"&gt;your API key&lt;/a&gt;(&lt;code&gt;OPENAI_API_KEY&lt;/code&gt;) to…&lt;/li&gt;

&lt;/ul&gt;
&lt;/div&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/3ru/gpt-translate" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;&lt;br&gt;
This is my very first OSS and I would be happy if you like it.

</description>
      <category>opensource</category>
      <category>i18n</category>
      <category>ai</category>
      <category>chatgpt</category>
    </item>
  </channel>
</rss>
