<?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: John Lago</title>
    <description>The latest articles on DEV Community by John Lago (@lagoja).</description>
    <link>https://dev.to/lagoja</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%2F937855%2F6b41e31a-74d7-436e-a06d-33731e1bc339.jpeg</url>
      <title>DEV Community: John Lago</title>
      <link>https://dev.to/lagoja</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lagoja"/>
    <language>en</language>
    <item>
      <title>Why We Ditched Vercel for Our NodeJS App</title>
      <dc:creator>John Lago</dc:creator>
      <pubDate>Fri, 12 Jul 2024 19:57:23 +0000</pubDate>
      <link>https://dev.to/jetify/why-we-ditched-vercel-for-our-nodejs-app-1jga</link>
      <guid>https://dev.to/jetify/why-we-ditched-vercel-for-our-nodejs-app-1jga</guid>
      <description>&lt;p&gt;In the world of web development, the search for the ideal hosting solution is never-ending. Like many others, we initially fell in love with Vercel for its user-friendly interface and near-zero setup. Vercel is an excellent solution for static sites, perfect for our websites and documentation. CDN caching makes everything fast, efficient, and cost-effective.&lt;/p&gt;

&lt;p&gt;Given our positive experience with Vercel for static sites, we decided to host our NodeJS servers there as well. We had several Remix servers we thought could be supported by edge functions. After all, isn't the future all about going serverless? We decided to host our authentication flow and dashboard app on Vercel using edge functions. Spoiler alert: it did not go well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Vercel Doesn’t Cut It
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Speed Issues: The Dream Dies
&lt;/h3&gt;

&lt;p&gt;Our first red flag was performance. Serverless functions on Vercel were not up to par in terms of speed. And it wasn’t just us—many developers have voiced &lt;a href="https://www.reddit.com/r/nextjs/comments/13vi7rz/anyone_else_have_trouble_with_slow_serverless/" rel="noopener noreferrer"&gt;similar frustrations&lt;/a&gt;. For an application handling critical user interactions like authentication, speed is paramount. The delays were noticeable, often around 600ms to 1 second.&lt;/p&gt;

&lt;h3&gt;
  
  
  Debugging Nightmares: The Endless Cycles
&lt;/h3&gt;

&lt;p&gt;Vercel detects the framework of your NodeJS server in an attempt to turn each route into an edge function. Server-side libraries may build successfully for edge functions yet encounter issues at runtime without notice. With most bugs not reproducible locally, and the remote environment is not something you can SSH into, endless trial and error becomes the norm. What’s worse, you may find out the package you need is not edge-function compatible at all.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cost Explosions: The $96K Surprise
&lt;/h3&gt;

&lt;p&gt;For customers, calculating usage is no longer as simple as total billable hours for a single EC2. To make it more concrete, a single JS server that contains ten routes will split into ten different edge functions. While Vercel gives you uptime and scalability guarantees, a &lt;a href="https://x.com/zemotion/status/1798558292681343039" rel="noopener noreferrer"&gt;shocking $96K bill&lt;/a&gt; may knock on your door if you get a spike in usage.&lt;/p&gt;

&lt;h3&gt;
  
  
  The bottom line
&lt;/h3&gt;

&lt;p&gt;Going serverless for an app that clearly needs a backend server? In hindsight, that should make us pause for a second. Just because the server is written in JavaScript, does not mean we should treat it differently from a server written in Go, Rust, or Python. The bottom line — infrastructure should be language and framework-agnostic.&lt;/p&gt;

&lt;h2&gt;
  
  
  The ultimate dream: an edge-function-like platform for Backend
&lt;/h2&gt;

&lt;p&gt;Without a good substitute for Vercel’s edge functions, we Jetifiers like to build our own.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres-3.cloudinary.com%2Fjetpack-io%2Fimage%2Fupload%2Fq_auto%2Fv1%2Fblog%2Fdeployment.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres-3.cloudinary.com%2Fjetpack-io%2Fimage%2Fupload%2Fq_auto%2Fv1%2Fblog%2Fdeployment.png" alt="Jetify Deploy Dashboard"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Introducing &lt;a href="https://www.jetify.com/deploy" rel="noopener noreferrer"&gt;Jetify Deploy&lt;/a&gt;, a platform that incorporates the best properties of edge-function while avoiding its drawbacks:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;No Dockerfiles needed: don’t know how to write Dockerfiles or Kubernetes YAMLs? No problem, you don’t have to. However, you can provide a &lt;a href="https://www.jetify.com/devbox/docs/configuration/" rel="noopener noreferrer"&gt;devbox.json&lt;/a&gt; or Dockerfile if you want more control.&lt;/li&gt;
&lt;li&gt;No application code change: there are no special libraries you need to import or hidden route splitting that happens behind the scenes.&lt;/li&gt;
&lt;li&gt;Zero DevOps: no Terraform, Ansible, or shell scripts needed. Import your application code from GitHub, and we will handle the rest.&lt;/li&gt;
&lt;li&gt;Stateless: deployments are as disposable assets, not precious pets. Past deployments are kept as idle copies until needed.&lt;/li&gt;
&lt;li&gt;Easy cost management: Your server spins up when it gets a request and spins down when idle. You won’t get a hundred edge functions just to handle a surge in requests.&lt;/li&gt;
&lt;li&gt;Write once, run anywhere: wrap your project with &lt;a href="https://www.jetify.com/devbox" rel="noopener noreferrer"&gt;Devbox&lt;/a&gt; to get an identical environment for local, preview, and production. Any issues encountered on production can be reproduced locally. Or anywhere.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Looking ahead
&lt;/h2&gt;

&lt;p&gt;We have successfully migrated our authentication flow and dashboard app from Vercel edge functions to Jetify Cloud. The transition was smooth, and we have seen significant improvements in speed, debuggability, and cost.&lt;/p&gt;

&lt;p&gt;We are excited to share our journey and encourage others facing similar challenges to explore new possibilities. You can try Jetify Cloud for your own solo projects with a 30-day free trial. Jetify Cloud accounts also come with access to the &lt;a href="https://www.jetify.com/cache" rel="noopener noreferrer"&gt;Jetify Cache&lt;/a&gt;, and &lt;a href="https://www.jetify.com/devbox/docs/cloud/secrets" rel="noopener noreferrer"&gt;Jetify Secrets&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;Stay tuned as we continue to refine our setup and share more insights. If you are struggling with your current hosting solution, we hope our story inspires you to find your perfect fit. You can follow us on &lt;a href="https://twitter.com/jetify_com" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;, or chat with our developers live on our &lt;a href="https://discord.gg/jetify" rel="noopener noreferrer"&gt;Discord Server&lt;/a&gt;. We also welcome issues and pull requests on our &lt;a href="https://github.com/jetify-com/devbox" rel="noopener noreferrer"&gt;Github Repo&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>devops</category>
      <category>startup</category>
    </item>
    <item>
      <title>Don't Rebuild Yourself - an Intro to Nix Package Caches</title>
      <dc:creator>John Lago</dc:creator>
      <pubDate>Fri, 12 Jul 2024 19:36:54 +0000</pubDate>
      <link>https://dev.to/jetify/dont-rebuild-yourself-an-intro-to-nix-package-caches-4c4k</link>
      <guid>https://dev.to/jetify/dont-rebuild-yourself-an-intro-to-nix-package-caches-4c4k</guid>
      <description>&lt;p&gt;In previous blog posts, we’ve talked about how we speed up Devbox installs by &lt;a href="https://www.jetify.com/blog/how-we-sped-up-nix-package-installs-in-devbox/" rel="noopener noreferrer"&gt;fetching package closures directly&lt;/a&gt; from the official Nix Cache. This blog post will dig a bit more into how a Nix cache solution works, and how it can speed up your package installation time. In addition to covering the official Nix cache, we’ll talk about how you can integrate the &lt;a href="https://www.jetify.com/cache" rel="noopener noreferrer"&gt;Jetify Cache&lt;/a&gt; with Devbox to speed up your shells and share your custom packages across your team.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building Reproducible Packages with Nixpkgs
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://www.github.com/NixOS/nixpkgs" rel="noopener noreferrer"&gt;Nixpkgs repository&lt;/a&gt; provides over 100,000 packages, and supports multiple  architectures and operating systems. Nix packages define all their requirements and dependencies within their build definition, making them reproducible and isolating them from the dependencies on your host machine. This means you can install multiple versions of the same Nix package on the same machine without conflicts.&lt;/p&gt;

&lt;p&gt;This isolation comes with a trade-off. Due to the unique way Nix defines packages, it can't simply download upstream binaries. Instead, it needs to ensure the package links its dependencies in the Nix store correctly. The only way to guarantee a package does this is to build the package and it’s dependencies from source, and link it’s dependencies within the Nix store.&lt;/p&gt;

&lt;p&gt;All that building can add up. Building a package like MongoDB can take up to 30 minutes, and that's just for MongoDB. Building a full closure from source can take hours, and updating a dependency in the graph means you have to rebuild the whole universe. All that building leads to the &lt;a href="https://xkcd.com/303/" rel="noopener noreferrer"&gt;obligatory XKCD comic&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimgs.xkcd.com%2Fcomics%2Fcompiling.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimgs.xkcd.com%2Fcomics%2Fcompiling.png" alt="Two engineers sword fighting on chairs, while their code compiles in the background"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Speeding up Installations with Nix Package Caches
&lt;/h2&gt;

&lt;p&gt;Fortunately, Nix's reproducibility and isolation also makes it easy to share and reuse the build outputs of packages. Each Nix package has a &lt;a href="https://www.jetify.com/blog/how-we-sped-up-nix-package-installs-in-devbox/" rel="noopener noreferrer"&gt;unique store path&lt;/a&gt; determined by the hash of its inputs. This unique store path means Nix can identify and reuse build outputs easily.&lt;/p&gt;

&lt;p&gt;This reuse happens in two layers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Nix can reuse existing packages and outputs in your &lt;strong&gt;Nix Store&lt;/strong&gt;. When Nix starts building your package's dependencies, it first checks if a package with the correct store path exists in your local store, and then reuses that store path. The Nix Store enables sharing packages on a single machine, but you'll need a different layer if you want to share across machines.&lt;/li&gt;
&lt;li&gt;To share across machines, you need a Nix Cache. If someone is building and pushing the packages you need to a cache, you can skip building and download precisely what you need. Developers can configure multiple Nix caches as "substituters," which tell the Nix Daemon where to look for “substitute” store paths that aren't in their current Nix store.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The largest cache is the &lt;a href="https://cache.nixos.org/" rel="noopener noreferrer"&gt;Public Cache&lt;/a&gt; maintained by the NixOS Foundation. The Foundation knows that users want to avoid constantly rebuilding, so they build most of Nixpkgs packages in &lt;a href="https://github.com/NixOS/hydra" rel="noopener noreferrer"&gt;Hydra&lt;/a&gt; (Nix’s CI build system) and push them to the public cache. For the most popular binaries and platforms, the Nix Public Cache has you covered.&lt;/p&gt;

&lt;p&gt;The public cache does have some gaps, however, that your project can fall into&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Packages outside the Nixpkgs like custom packages on our machine or flakes hosted in public repositories.&lt;/li&gt;
&lt;li&gt;Packages such as MongoDB, Terraform, and Vault aren't hosted in the Nix cache because they lack an open-source license.&lt;/li&gt;
&lt;li&gt;Older packages, or packages on less popular platforms, can be garbage collected or excluded from the public cache.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For this reason, many developers set up their own Nix caches to use as substituters for their custom packages. Technically, any machine running Nix can serve as a cache or substituter for another machine. If you're trying to support a team, however, managing issues like trust, access control, and populating the cache with the latest packages can take a lot of extra effort and development.&lt;/p&gt;

&lt;h2&gt;
  
  
  Jetify Cache: A Package Cache designed for Devbox and Nix
&lt;/h2&gt;

&lt;p&gt;For teams that want a cache without the extra overhead, we built the &lt;a href="https://www.jetify.com/cache" rel="noopener noreferrer"&gt;Jetify Cache&lt;/a&gt;. Jetify Cache is an enterprise grade Nix Cache that integrates nicely with Devbox, so you can speed up your shells with little extra effort.&lt;/p&gt;

&lt;p&gt;Our Jetify Cache offers two solutions that can help your team develop faster:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;For packages in Nixpkgs that are not available in the Nix Cache, we offer the &lt;a href="https://www.jetify.com/devbox/docs/cloud/cache/prebuilt_cache" rel="noopener noreferrer"&gt;&lt;strong&gt;Jetify Prebuilt Cache&lt;/strong&gt;&lt;/a&gt;. This provides prebuilt versions of packages not in the official Nix Cache. If you have a Jetify Cloud account, Devbox will automatically configure the Prebuilt cache as a substituter. When Devbox prepares to install a package, it will use the Prebuilt cache if there are any gaps in your local Nix Store or the official Nix cache.&lt;/li&gt;
&lt;li&gt;For your custom packages and flakes, we offer the &lt;a href="https://www.jetify.com/devbox/docs/cloud/cache" rel="noopener noreferrer"&gt;&lt;strong&gt;Jetify Private Cache&lt;/strong&gt;&lt;/a&gt;. Jetify Private Cache lets you share binaries across all your devices and developers. After you build your Devbox project (either locally, or in CI), you can run &lt;code&gt;devbox cache upload&lt;/code&gt; to push the entire closure of your project to the cache. Developers who share your Jetify Cloud Project can then easily download their packages from the cache without building from source.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Devbox: Optimized for Nix Package Caching
&lt;/h2&gt;

&lt;p&gt;Devbox can automatically configure the Jetify Cache caches for you when you authenticate with Jetify Cloud With the Jetify Cache enabled, you now have 4 layers where Devbox and Nix can check for binaries before building from source:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The Nix Store (&lt;code&gt;/nix/store&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Your Jetify Private Cache&lt;/li&gt;
&lt;li&gt;The Official Nix Cache (cache.nixos.org)&lt;/li&gt;
&lt;li&gt;The Jetify Prebuilt Cache.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As mentioned above, Devbox can install packages by copying them directly from the cache, without needing to re-run evaluation steps. We do this by retrieving the store paths directly from &lt;a href="https://www.nixhub.com/" rel="noopener noreferrer"&gt;Nixhub&lt;/a&gt; (our Nix Package Search engine) at install time, and then save the store paths in our &lt;code&gt;devbox.lock&lt;/code&gt; file. With this optimized cache experience, you can start reducing your installation times in seconds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep Up To Date on Jetify and Devbox
&lt;/h2&gt;

&lt;p&gt;If you want to speed up your package installs, the Jetify Prebuilt Cache is available to any developer who signs up for a free &lt;a href="https://cloud.jetify.com/" rel="noopener noreferrer"&gt;Jetify Cloud&lt;/a&gt; account. If you have custom packages or binaries you want to cache, you can check out our &lt;a href="https://www.jetify.com/pricing" rel="noopener noreferrer"&gt;pricing plans&lt;/a&gt; for Jetify Cloud.&lt;/p&gt;

&lt;p&gt;We’d love to hear your feedback on Devbox and Jetify Cache. You can follow us on &lt;a href="https://twitter.com/jetify_com" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;, or chat with our developers live on our &lt;a href="https://discord.gg/jetify" rel="noopener noreferrer"&gt;Discord Server&lt;/a&gt;. We also welcome issues and pull requests on our &lt;a href="https://github.com/jetify-com/devbox" rel="noopener noreferrer"&gt;Github Repo&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>nix</category>
      <category>learning</category>
      <category>devops</category>
    </item>
    <item>
      <title>TypeID-JS: Type Safe, K-Sortable Unique IDs for Javascript</title>
      <dc:creator>John Lago</dc:creator>
      <pubDate>Tue, 09 Jul 2024 16:29:27 +0000</pubDate>
      <link>https://dev.to/jetify/typeid-js-type-safe-k-sortable-unique-ids-for-javascript-djh</link>
      <guid>https://dev.to/jetify/typeid-js-type-safe-k-sortable-unique-ids-for-javascript-djh</guid>
      <description>&lt;p&gt;Since we first announced &lt;a href="https://github.com/jetify-com/typeid" rel="noopener noreferrer"&gt;TypeID&lt;/a&gt; last year, we've seen significant adoption and interest from the community, with 23 different language clients contributed by the community and 90,000 weekly NPM downloads of our Typescript Implementation.&lt;/p&gt;

&lt;p&gt;Last week, we released version 1.0 of our Typescript implementation, &lt;a href="https://github.com/jetify-com/typeid-js" rel="noopener noreferrer"&gt;TypeID-JS&lt;/a&gt;. To celebrate this release, we wanted to share more about why we wrote TypeID, and how we use it to ensure type safety at Jetify.&lt;/p&gt;

&lt;h2&gt;
  
  
  Type Safety and Unique Identifiers
&lt;/h2&gt;

&lt;p&gt;We developed the idea for TypeID while building &lt;a href="https://www.jetify.com/cloud" rel="noopener noreferrer"&gt;Jetify Cloud&lt;/a&gt;, our solution for deploying and managing &lt;a href="https://www.jetify.com/devbox" rel="noopener noreferrer"&gt;Devbox&lt;/a&gt; or Docker based projects across your team. Jetify Cloud's architecture has many different entities we need to manage: Orgs, Users, Deployments, Secrets, and Projects, all of which require unique identifiers to distinguish them.&lt;/p&gt;

&lt;p&gt;Originally, we started by following best practices and assigning a UUID to each instance of an entity. Still, we quickly ran into a problem: UUIDv7 lacks type safety! Take the code below as an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getMember&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;memberId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UUID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;orgId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UUID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;member&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;organization&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;authClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;organizations&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;members&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;organization_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;orgId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;member_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;memberId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;member&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;organization&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;This function uses two UUIDs to look up a member and organization. However, the function cannot ensure that &lt;code&gt;memberID&lt;/code&gt; and &lt;code&gt;orgID&lt;/code&gt; represent the correct entity! If a developer accidentally uses a &lt;code&gt;memberID&lt;/code&gt; where we were expecting an &lt;code&gt;orgID&lt;/code&gt;, we would only discover the issue at runtime.&lt;/p&gt;

&lt;p&gt;As we were looking for solutions to this problem, we encountered Stripe's &lt;a href="https://dev.to/stripe/designing-apis-for-humans-object-ids-3o5a"&gt;Object ID&lt;/a&gt;, which encodes type information into IDs using a prefix. This seemed like a great solution, but unfortunately, we couldn't find a well-defined standard for consistently implementing typed IDs across multiple languages.&lt;/p&gt;

&lt;h2&gt;
  
  
  TypeID: K-sortable, type-safe, globally unique identifiers
&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://www.github.com/jetify-com/typeid" rel="noopener noreferrer"&gt;TypeID&lt;/a&gt; is our attempt to create such a consistent standard. TypeID is a type-safe, K-sortable, globally unique identifier inspired by Stripe's prefixed types. TypeID also provides a consistent standard for other languages to implement their clients and libraries.&lt;/p&gt;

&lt;p&gt;TypeIDs encode unique identifiers as a lowercase string with three parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A prefix that represents the ID’s type (63 chars, lowercase ASCII letters)&lt;/li&gt;
&lt;li&gt;An underscore (&lt;code&gt;_&lt;/code&gt;) separator&lt;/li&gt;
&lt;li&gt;A 128-bit UUIDv7 encoded as a 26-character string using a modified base32 encoding.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;  &lt;span class="nx"&gt;user_2x4y6z8a0b1c2d3e4f5g6h7j8k&lt;/span&gt;
  &lt;span class="err"&gt;└──┘&lt;/span&gt; &lt;span class="err"&gt;└────────────────────────┘&lt;/span&gt;
  &lt;span class="kd"&gt;type&lt;/span&gt;    &lt;span class="nx"&gt;uuid&lt;/span&gt; &lt;span class="nf"&gt;suffix &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;base32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this format, a TypeID-compatible client can encode and decode type information into your IDs and then run checks at a build or compile time to ensure you are using the right ID. For example, if we wanted to create a random TypeID for a user entity, we could do something like this:&lt;/p&gt;

&lt;p&gt;With TypeID, we can also add type checks to our functions and catch errors at runtime. Rewriting the example above, we can now be sure that developers will use the proper IDs in the right place:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;TypeID&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="s1"&gt;typeid-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;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getMember&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;memberId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TypeID&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;member&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;orgId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TypeID&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;org&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In addition to type safety, this format has a few properties that make it friendly for developers to use:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;UUIDv7 compatible:&lt;/strong&gt; You can easily &lt;a href="https://www.jetify.com/typeid" rel="noopener noreferrer"&gt;convert&lt;/a&gt; a TypeID into a UUID by removing the prefix and decoding the suffix.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;K-sortable:&lt;/strong&gt; You can use a TypeID as a sortable primary key in your database with good locality.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;URL safe:&lt;/strong&gt; We use TypeIDs in our URLs to make them easy to copy, paste, and share. Including TypeIDs in the URL makes simplifies generating page state.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Easily selectable:&lt;/strong&gt; You can copy and paste it by double-clicking (Try it!)&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  New Features in TypeID-JS v1.0
&lt;/h2&gt;

&lt;p&gt;Today, we're announcing version 1.0 of our TypeID-JS library. This update adds several new features to improve usability and type safety, including:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Unboxed, function-based, streamable TypeIDs&lt;/strong&gt;: This makes it possible to serialize TypeIDs without casting them to strings and lets you use TypeIDs as keys in Maps and Sets.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stricter Type and Runtime checking:&lt;/strong&gt; TypeID now throws an error if you attempt to parse an empty string or a typeid with the wrong prefix.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compatibility with TypeID spec v3:&lt;/strong&gt; JS TypeIDs can now use underscores in the prefix. For example: &lt;code&gt;pro_subscription_2x4y6z8a0b1c2d3e4f5g6h7j8k&lt;/code&gt; is a valid TypeID with prefix &lt;code&gt;pro_subscription&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  How to Use TypeID with your project
&lt;/h2&gt;

&lt;p&gt;You can add TypeID to your JS project using your NodeJS package manager of choice. Not using JS? TypeID has 26 different implementations, ranging from Go to OCaml to SQL. If you’re interested in writing your own implementation of TypeID, you can check our our &lt;a href="https://github.com/jetify-com/typeid/tree/main/spec" rel="noopener noreferrer"&gt;formal specification&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Looking to Power-Up your Development Team?
&lt;/h2&gt;

&lt;p&gt;Our team at Jetify builds powerful developer tools. Simplify your deployments and projects with &lt;a href="https://www.jetify.com/cloud" rel="noopener noreferrer"&gt;Jetify Cloud&lt;/a&gt;, or automate onboarding + dev environments with &lt;a href="https://www.jetify.com/devbox" rel="noopener noreferrer"&gt;Devbox&lt;/a&gt;. You can follow us on &lt;a href="https://twitter.com/jetify_com" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;, or chat with our developers live on our &lt;a href="https://discord.gg/jetify" rel="noopener noreferrer"&gt;Discord Server&lt;/a&gt;. We also welcome issues and pull requests on our &lt;a href="https://github.com/jetify-com/devbox" rel="noopener noreferrer"&gt;Github Repo&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
