<?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: David Gomes</title>
    <description>The latest articles on DEV Community by David Gomes (@davidgomes).</description>
    <link>https://dev.to/davidgomes</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%2F1012473%2F0eff3313-47e9-4a7a-9c09-22624a354a5f.jpeg</url>
      <title>DEV Community: David Gomes</title>
      <link>https://dev.to/davidgomes</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/davidgomes"/>
    <language>en</language>
    <item>
      <title>app.build – Open-Source AI Agent That Builds Full-Stack Apps</title>
      <dc:creator>David Gomes</dc:creator>
      <pubDate>Wed, 04 Jun 2025 20:41:52 +0000</pubDate>
      <link>https://dev.to/neon-postgres/appbuild-open-source-ai-agent-that-builds-full-stack-apps-1cmg</link>
      <guid>https://dev.to/neon-postgres/appbuild-open-source-ai-agent-that-builds-full-stack-apps-1cmg</guid>
      <description>&lt;p&gt;Code generation has been one of the most interesting use cases for LLMs. While the best models can generate decent code for isolated problems, there is a big gap between these code snippets and fully functional applications. Agent-based solutions are better suited to create apps. To close the gap, an agent needs to iterate on the code, test the result and make decisions based on the feedback - either human comments or technical (like logs, test results, linters output etc.). In the last few months, a lot of AI app builders have come to market to tackle this problem, but the gap is not closed yet.&lt;/p&gt;

&lt;p&gt;And today, Neon is launching app.build - an open-source agent that can build and deploy full-stack applications, with end-to-end tests and automated deployments. We want to build a community around this project, since we know a lot of developers are interested in hacking in this space, particularly by bringing their own models and doing most things locally.&lt;/p&gt;

&lt;h2&gt;
  
  
  How can I try it then?
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx @app.build/cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This very simple command is all you need to get started. Notice that, by default, it will ask you to sign in with GitHub. Any application that you generate will have its own repository (in your GitHub account), and will be deployed to the Internet with a real backend and a real database. This is our "managed service" experience. We're also working on a smoother way for you to run everything locally (which will include being able to choose which models you want for which tasks, and even self-hosted models).&lt;/p&gt;

&lt;h2&gt;
  
  
  Can I run this locally?
&lt;/h2&gt;

&lt;p&gt;Yes, everything runs locally. Our &lt;a href="https://dealsbe.com/" rel="noopener noreferrer"&gt;README.md&lt;/a&gt; contains instructions for how to run this locally, but we have yet to create a full guide for running both the CLI and the agent locally with more detail.&lt;/p&gt;

&lt;p&gt;We also want to write down instructions on how you can bring your own models (including self-hosted ones).&lt;/p&gt;

&lt;h2&gt;
  
  
  What features does the platform offer?
&lt;/h2&gt;

&lt;p&gt;Our CLI allows both creating new apps from scratch, and iterating on previously created apps (add new features or other types of changes). It is extremely barebones for now!&lt;/p&gt;

&lt;p&gt;But our platform gives you:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;An authentication provider (it defaults to Neon Auth)&lt;/li&gt;
&lt;li&gt;A hosted database (it defaults to Neon Postgres)&lt;/li&gt;
&lt;li&gt;Your app's frontend and backend get deployed immediately (in Neon and Koyeb's infrastructure)&lt;/li&gt;
&lt;li&gt;Hosted repository on your own GitHub account&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  How does the agent work?
&lt;/h2&gt;

&lt;p&gt;We've taken a lot of steps towards having an agent architecture that is focused on generating really high-quality applications that actually work as intended. This is why our agent writes end-to-end tests and actually runs them to succession as part of the generation pipeline.&lt;/p&gt;

&lt;p&gt;Furthermore, we have a very solid base template for every app (for now, just 1 template, which is for web apps), and we made sure that the agent is extremely well-versed on all the technologies that are used in this template (Fastify, Drizzle, React, Vite, etc.).&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%2F2f947yjm6ja7a6a2fmrm.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%2F2f947yjm6ja7a6a2fmrm.png" alt="how it works" width="800" height="728"&gt;&lt;/a&gt;&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%2Fwu86mlueqtzcesnx6ksy.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%2Fwu86mlueqtzcesnx6ksy.png" alt="Image description" width="800" height="542"&gt;&lt;/a&gt;&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%2Fb50pvo1zzudyv7pzkawb.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%2Fb50pvo1zzudyv7pzkawb.png" alt="Image description" width="800" height="639"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our agent follows the "divide-and-conquer" principle — app creation is decomposed into multiple tasks, and each can be solved independently. Furthermore, those tasks themselves may have their own subtasks, so we don't rely on LLMs generating large chunks of code at once. Each particular task passes a series of checks (e.g. Does it compile? Does it pass ESLint? Does it pass tests?), thus ensuring the final app works.&lt;/p&gt;

&lt;p&gt;In future blog posts and talks, we'll definitely dive deeper into the inner workings of the agent.&lt;/p&gt;

&lt;h2&gt;
  
  
  How can I get involved?
&lt;/h2&gt;

&lt;p&gt;For now, we're hacking over at &lt;a href="https://github.com/appdotbuild" rel="noopener noreferrer"&gt;github.com/appdotbuild&lt;/a&gt;. You can see all the code, all the commits and all of our planned tasks. We hope to create a Discord channel, and a proper public-facing roadmap soon!&lt;/p&gt;

&lt;p&gt;We're also currently working on more blog posts and videos explaining our code generation pipeline, and other architectural decisions we made while building the agent.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Wrapping My Mind Around Node.js Runtimes</title>
      <dc:creator>David Gomes</dc:creator>
      <pubDate>Fri, 22 Nov 2024 22:34:32 +0000</pubDate>
      <link>https://dev.to/neon-postgres/wrapping-my-mind-around-nodejs-runtimes-4elp</link>
      <guid>https://dev.to/neon-postgres/wrapping-my-mind-around-nodejs-runtimes-4elp</guid>
      <description>&lt;h3&gt;
  
  
  A look at Deno and Bun and how they work differently from Node.js
&lt;/h3&gt;

&lt;p&gt;There’s been a lot of innovation in the last few years in Node.js runtimes. Node.js used to be the only viable option, but now there’s other contenders such as Bun and Deno. But are they ready for prime time? When should they be used, and by whom?&lt;/p&gt;

&lt;h2&gt;
  
  
  Wait, what even is a JavaScript runtime?
&lt;/h2&gt;

&lt;p&gt;Good question. JavaScript wasn’t really built for the server. In fact, JavaScript wasn’t really “built” at all. What we think of as JS is just a specification.&lt;/p&gt;

&lt;p&gt;A runtime is what brings that specification to life. It’s the environment that executes JavaScript code. When you’re working in a browser, the browser provides the runtime. But on a server, you need something else. That’s where Node.js came in and where these new runtimes are shaking things up.&lt;/p&gt;

&lt;p&gt;A JavaScript runtime typically consists of several key components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;    &lt;strong&gt;JavaScript Engine.&lt;/strong&gt; This is the core that interprets and executes JavaScript code. V8 (used by Node.js and Chrome) is a famous example.&lt;/li&gt;
&lt;li&gt;    &lt;strong&gt;Event loop.&lt;/strong&gt; Manages asynchronous operations, allowing non-blocking I/O operations.&lt;/li&gt;
&lt;li&gt;    &lt;strong&gt;APIs.&lt;/strong&gt; Provides interfaces for system-level operations like file I/O, networking, and timers.&lt;/li&gt;
&lt;li&gt;    Standard library. A set of built-in modules and functions that developers can use out of the box.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Node’s ability to handle thousands of concurrent connections with its non-blocking I/O model has made it particularly popular for real-time applications, APIs, and microservices architectures. And it is still the most popular “web technology” according to the &lt;a href="https://survey.stackoverflow.co/2024" rel="noopener noreferrer"&gt;2024 Stack Overflow survey&lt;/a&gt;:&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%2F2r70th3828zw2szcxamv.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%2F2r70th3828zw2szcxamv.png" alt="web frameworks and technologies" width="800" height="177"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The problems with Node.js
&lt;/h2&gt;

&lt;p&gt;But Node is not without its detractors—including the person who initially built Node, &lt;a href="https://x.com/rough__sea" rel="noopener noreferrer"&gt;Ryan Dahl&lt;/a&gt;. In a 2019 jsconf talk titled &lt;a href="https://www.youtube.com/watch?v=M3BM9TB-8yA" rel="noopener noreferrer"&gt;10 Things I Regret About Node.js&lt;/a&gt;, Dahl lists the problems he now sees in Node, such as…&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;    &lt;strong&gt;Security.&lt;/strong&gt; By default, the module system in Node.js allows any package to access the file system, network, and environment variables. This poses significant security risks, especially when using third-party modules.&lt;/li&gt;
&lt;li&gt;   &lt;strong&gt;Package management.&lt;/strong&gt; The package.json file, npm, and the Node modules system have become overly complex. There’s also various security issues around npm (&lt;a href="https://stacklok.com/blog/how-npm-install-scripts-can-be-weaponized-a-real-life-example-of-a-harmful-npm-package" rel="noopener noreferrer"&gt;like the postinstall scripts&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;    &lt;strong&gt;Build system complexity.&lt;/strong&gt; Node’s build system, particularly for native modules, has become unnecessarily complicated over time. Basically, supporting both CommonJS and ES modules made Node.js much more complex.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, all this together has led a few people to think they can do better.&lt;/p&gt;

&lt;h2&gt;
  
  
  The new runtimes in town
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Deno: Security-oriented, modern JavaScript
&lt;/h3&gt;

&lt;p&gt;Ryan Dahl chose to take the learnings from Node and built &lt;a href="https://deno.com/" rel="noopener noreferrer"&gt;Deno&lt;/a&gt;. Deno addresses many of the concerns he had with Node.js:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;    &lt;strong&gt;Focus on security.&lt;/strong&gt; Deno runs code in a sandbox by default. Accessing the file system, network, or environment variables requires explicit permissions. This approach significantly reduces the risk of malicious code execution.&lt;/li&gt;
&lt;li&gt;    &lt;strong&gt;Built-in TypeScript support.&lt;/strong&gt; Unlike Node.js, which requires additional setup for TypeScript, Deno supports TypeScript out of the box. This integration streamlines development and improves code quality.&lt;/li&gt;
&lt;li&gt;    &lt;strong&gt;Standard modules.&lt;/strong&gt; Deno provides a standard library of high-quality, audited modules. This reduces dependency on third-party packages for common functionalities.&lt;/li&gt;
&lt;li&gt;    &lt;strong&gt;Browser compatibility.&lt;/strong&gt; Deno aims to be as close as possible to browser JavaScript. It uses web standard APIs where possible, making it easier for developers to write code that works both in the browser and on the server.&lt;/li&gt;
&lt;li&gt;    &lt;strong&gt;Import URLs.&lt;/strong&gt; Instead of using a package manager like npm, Deno allows modules to be imported directly via URLs.&lt;/li&gt;
&lt;li&gt;        This will somewhat change with Deno v2, more on this later.&lt;/li&gt;
&lt;li&gt;    &lt;strong&gt;Single executable.&lt;/strong&gt; Deno ships as a single executable with no external dependencies, making it easy to install and use across different environments.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Deno is gaining traction, especially among developers who appreciate its modern features and security-first approach. It’s particularly attractive for projects that can benefit from its TypeScript integration and don’t rely heavily on Node-specific libraries. &lt;/p&gt;

&lt;p&gt;Deno also provides infrastructure beyond the runtime. Tests, linters, and formatters are also included. You can also deploy your applications using Deno’s serverless environment, Deno Deploy (learn &lt;a href="https://neon.tech/docs/guides/deno" rel="noopener noreferrer"&gt;how to use Neon with Deno Deploy&lt;/a&gt;), and build entire applications using Deno’s framework, &lt;a href="https://fresh.deno.dev/" rel="noopener noreferrer"&gt;Fresh&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here’s a simple setup with Deno to use Neon. The Deno-specific things are the import &lt;code&gt;(@neon/serverless is called @neondatabase/serverless in NPM)&lt;/code&gt; and the &lt;code&gt;Deno.env.get&lt;/code&gt; bits. Also, this is a Deno v2 example (which is currently in “canary”).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { neon } from "@neon/serverless";

// Get the connection string from the environment variable "DATABASE_URL"
const databaseUrl = Deno.env.get("DATABASE_URL")!;

if (!databaseUrl) {
  throw new Error(`Please add a DATABASE_URL environment variable.`);
}

const sql = neon(databaseUrl);

const rows = await sql`SELECT version()`;

console.log(rows[0].version);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To run this, call:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DATABASE_URL=$DATABASE_URL deno test.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(And notice how Deno will ask for permission to read environment variables and make network requests &lt;a href="https://docs.deno.com/runtime/fundamentals/security/" rel="noopener noreferrer"&gt;at runtime.&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;To show the speed of progress with Deno, up until a few months ago, the above code would have used an import URL, such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import * as postgres from 'https://deno.land/x/postgres@v0.17.0/mod.ts';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Deno just released version &lt;a href="https://deno.com/blog/v1.46" rel="noopener noreferrer"&gt;1.46,&lt;/a&gt; which will be the last 1.X version. Deno 2 is changing in response to feedback from the community and a greater understanding of the initial strict choices of the runtime.&lt;/p&gt;

&lt;p&gt;Take imports. Originally the idea was to have simple URLs like &lt;a href="https://deno.land/x/postgres@v0.17.0/mod.ts" rel="noopener noreferrer"&gt;https://deno.land/x/postgres@v0.17.0/mod.ts&lt;/a&gt;. As Deno put it:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Designing Deno’s module system around HTTP imports was ambitious. It aimed to replace npm with a distributed system over HTTP, aligning with how ES Modules work in browsers. This eliminated the need for package.json files and node_modules folders, simplifying project structures.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But the reality wasn’t as clean. Deno found that dependency management, clutter, and reliability were all a problem with this approach. So, they’ve launched &lt;a href="https://jsr.io/" rel="noopener noreferrer"&gt;JSR&lt;/a&gt;, the JavaScript Registry. This is akin to npm in node, but TypeScript and ECMAScript-native. All you have to do is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;deno add @neon/serverless
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you’re ready to roll.&lt;/p&gt;

&lt;p&gt;Like Node.js, Deno is built on the V8 engine. Originally, Deno wasn’t supposed to be compatible with Node.js. But, as with import URLs, pragmatism beat out idealism. The Deno team realized that compatibility with the vast Node.js ecosystem would significantly increase Deno’s adoption and usefulness. As a result, they’ve been working on Node.js compatibility layers, allowing developers to use many Node.js packages and APIs within Deno projects, thereby bridging the gap between the two runtimes.&lt;/p&gt;

&lt;p&gt;If you want to learn more, I highly recommend &lt;a href="https://www.youtube.com/watch?v=tZBCq8Ijkgw" rel="noopener noreferrer"&gt;the recent participation of Ryan Dahl on the “Syntax” podcast&lt;/a&gt; to learn more about Deno v2.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bun: A performance-focused Node replacement
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://bun.sh/" rel="noopener noreferrer"&gt;Bun&lt;/a&gt; is a little different. It was Node-compatible out of the gate and not looking to right-the-wrongs of Node.js. But, as it grew, it started to evolve towards a slightly different direction.&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%2Fao8ns45guc9vi4b7kbkn.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%2Fao8ns45guc9vi4b7kbkn.png" alt="Sever-side rendering React" width="800" height="644"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Benchmarking is hard. We at Neon are definitely very well aware of that, but my anecdotal experience is that Bun is indeed really fast. How fast exactly is very hard to measure, of course.&lt;/p&gt;

&lt;p&gt;Like Deno, Bun is looking to rely on JavaScript primitives and code simplicity. Here’s &lt;a href="https://github.com/neondatabase/examples/tree/main/with-bun" rel="noopener noreferrer"&gt;Neon running with Bun&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { neon } from "@neondatabase/serverless";

const databaseUrl = process.env.DATABASE_URL;

if (!databaseUrl) {
  throw new Error(`Please add a DATABASE_URL environment variable.`);
}

const sql = neon(databaseUrl);

const rows = await sql`SELECT version()`;

console.log(rows[0].version);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To call this, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DATABASE_URL=$DATABASE_URL bun test.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Bun’s approach to improving the JavaScript runtime environment focuses on several key areas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;    &lt;strong&gt;Performance.&lt;/strong&gt; Built on the JavaScriptCore engine (used by Safari), Bun is designed for speed from the ground up. Its fast startup times and efficient execution make it particularly suitable for serverless environments and microservices.&lt;/li&gt;
&lt;li&gt;    &lt;strong&gt;TypeScript support.&lt;/strong&gt; Similar to Deno, Bun offers out-of-the-box TypeScript support. However, Bun takes it a step further by transpiling TypeScript at runtime, eliminating the need for separate build steps in many cases.&lt;/li&gt;
&lt;li&gt;    &lt;strong&gt;Enhanced APIs.&lt;/strong&gt; Bun provides additional APIs that aren’t available in Node.js, such as the Bun.file API for efficient file operations and the SQLite API for built-in database functionality.&lt;/li&gt;
&lt;li&gt;    &lt;strong&gt;Streamlined configuration.&lt;/strong&gt; Bun aims to reduce configuration overhead. For instance, it automatically loads environment variables from .env files, simplifying local development and deployment processes.&lt;/li&gt;
&lt;li&gt;    &lt;strong&gt;All-in-one toolkit.&lt;/strong&gt; Bun isn’t just a runtime; it’s a complete toolkit. It includes a package manager, test runner (which &lt;a href="https://nodejs.org/api/test.html" rel="noopener noreferrer"&gt;Node.js now has as well&lt;/a&gt;), and bundler, all optimized for performance. This integrated approach simplifies the development workflow and reduces the need for additional tools.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Bun team is rapidly iterating and adding some interesting features. For example, they introduced “&lt;a href="https://bun.sh/guides/http/hot" rel="noopener noreferrer"&gt;hot module reloading&lt;/a&gt;” for server-side code, a feature that’s been long desired in the Node.js ecosystem. Also, more recently, they added support for &lt;a href="https://x.com/jarredsumner/status/1825113318539006402" rel="noopener noreferrer"&gt;C code using TinyCC&lt;/a&gt; 🤯And I believe they led the way with &lt;a href="https://bun.sh/docs/api/sqlite" rel="noopener noreferrer"&gt;SQLite embedding&lt;/a&gt; (but Node.js has now caught up).&lt;/p&gt;

&lt;p&gt;While Bun is still young compared to Node.js and even Deno, its focus on performance and developer experience is attracting attention. It is particularly appealing for projects where raw speed is a priority, such as high-traffic web servers or compute-intensive apps.&lt;/p&gt;

&lt;p&gt;Furthermore, it’s also extremely appealing to use Bun not as your production runtime, but just as your package manager. We’re currently doing that with &lt;a href="https://github.com/neondatabase/neonctl" rel="noopener noreferrer"&gt;neonctl&lt;/a&gt;, purely because of Bun’s performance (we also want to migrate the CLI runtime to Bun at some point, due to its single-file &lt;a href="https://bun.sh/docs/bundler/executables" rel="noopener noreferrer"&gt;executable feature&lt;/a&gt; and overall performance).&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;First of all, I have to mention that there are a few other runtimes that are probably worth mentioning. Although, perhaps it’d be better to refer to some of them as “neo-runtimes” since they’re not necessarily full blown runtimes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;    &lt;a href="https://github.com/saghul/txiki.js/" rel="noopener noreferrer"&gt;https://github.com/saghul/txiki.js/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;    &lt;a href="https://github.com/cloudflare/workerd" rel="noopener noreferrer"&gt;https://github.com/cloudflare/workerd&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then, there’s the aspect of picking a runtime. This is a very hard decision and obviously migrating existing projects is even harder. But this is my very personal current thought process:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;    Use Node.js for anything that needs to live for really long, or doesn’t need Deno’s &lt;a href="https://docs.deno.com/runtime/fundamentals/security/" rel="noopener noreferrer"&gt;security model&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;    Use Deno if you want extra security, or if you specifically want to use &lt;a href="https://deno.com/deploy" rel="noopener noreferrer"&gt;Deno Deploy&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;        Don’t use Deno if all you care about is not transpiling TypeScript. Node.js will support TypeScript soon enough.&lt;/li&gt;
&lt;li&gt;    Use Bun if performance is the most important thing to you. Or, if you want to use some of Bun’s more “fun” features (Macros, embedded SQLite, etc.) and you don’t have a super critical requirement that your project outlives your time on Earth (Bun is afterall backed by a very early stage company).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s basically it, but I know this is all very subjective — do your own research! I really love Bun’s performance and I try to use Bun for all package management on my local machine. However, I would only use Bun as a production runtime under certain circumstances for now.&lt;/p&gt;

&lt;p&gt;If you’re looking for a more pessimistic take on new runtimes, I can recommend this &lt;a href="https://dev.to/thejaredwilcurt/bun-hype-how-we-learned-nothing-from-yarn-2n3j"&gt;blog post&lt;/a&gt;. But I tend to have a more positive outlook on new companies building cool new dev tooling.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>node</category>
    </item>
    <item>
      <title>Introducing Neon RLS: Simplifying Row-Level Security For Postgres</title>
      <dc:creator>David Gomes</dc:creator>
      <pubDate>Wed, 30 Oct 2024 18:15:50 +0000</pubDate>
      <link>https://dev.to/neon-postgres/introducing-neon-authorize-simplifying-row-level-security-for-postgres-14fp</link>
      <guid>https://dev.to/neon-postgres/introducing-neon-authorize-simplifying-row-level-security-for-postgres-14fp</guid>
      <description>&lt;p&gt;RLS policies in your codebase, verified by Neon&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%2Flinxgmufvhfmb9wclr6k.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%2Flinxgmufvhfmb9wclr6k.png" alt="Row Level Security" width="800" height="445"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Today we’re launching &lt;a href="https://neon.tech/docs/guides/neon-authorize" rel="noopener noreferrer"&gt;Neon RLS&lt;/a&gt;, a tool that aims to simplify the usage of Postgres row-level security policies while enabling new deployment models for app developers. With Neon RLS, you can manage RLS directly in your codebase and integrate with any authentication provider, making it easier to enforce fine-grained access control without added complexity.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every app needs a database. And every app needs authentication and authorization.&lt;/p&gt;

&lt;p&gt;However, it can be cumbersome to bind these things together. If you’ve worked on application backends before, it’s very likely you’ve seen code like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;try {
  const result = await query(
    `SELECT r.role_name
     FROM user_roles ur
     JOIN roles r ON ur.role_id = r.id
     WHERE ur.user_id = $1 AND r.role_name = $2`,
    [userId, "admin"]
  );

  if (result.rows.length &amp;gt; 0) {
    next();
  } else {
    res.status(403).json({ error: 'Access denied' });
  }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This type of database access is hard to properly secure. The core issue is that it’s quite easy to mess up the authorization check – &lt;code&gt;WHERE ur.user_id = $1 AND r.role_name = $2)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is where &lt;a href="https://www.postgresql.org/docs/current/ddl-rowsecurity.html" rel="noopener noreferrer"&gt;Row Security Policies&lt;/a&gt;) in Postgres come in. This feature allows developers to configure declarative access rules for their tables. As an example, let’s say you have the following &lt;code&gt;users&lt;/code&gt; table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Table "public.projects"
┌───────────────┬──────────────────────────┬──────────┬───────────────────┐
│    Column     │           Type           │ Nullable │      Default      │
├───────────────┼──────────────────────────┼──────────┼───────────────────┤
│ id            │ uuid                     │ not null │                   │
│ owner_user_id │ uuid                     │ not null │                   │
│ name          │ text                     │ not null │                   │
│ created_at    │ timestamp with time zone │          │ CURRENT_TIMESTAMP │
│ updated_at    │ timestamp with time zone │          │ CURRENT_TIMESTAMP │
└───────────────┴──────────────────────────┴──────────┴───────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To secure it with RLS, you’d configure the following rules:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ALTER TABLE projects ENABLE ROW LEVEL SECURITY;

-- Create policy for selecting own records
CREATE POLICY select_own_records ON public.projects
FOR SELECT
USING ((select owner_user_id = auth.user_id()));

-- Create policy for inserting rows
CREATE POLICY insert_policy ON public.projects
FOR INSERT
WITH CHECK ((select owner_user_id = auth.user_id()));

-- Here, we're missing similar policies for DELETE and UPDATE.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that &lt;code&gt;auth.user_id()&lt;/code&gt; and &lt;code&gt;auth.session()&lt;/code&gt; are part of the open-source &lt;a href="https://github.com/neondatabase/pg_session_jwt" rel="noopener noreferrer"&gt;pg_session_jwt&lt;/a&gt; Postgres extension, authored by the Neon team.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;info&lt;br&gt;
The advantage of RLS is that the authorization layer for your application is now declarative. Just like React.js brought declarative views to frontend development, RLS rules bring declarative access logic to backends.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;With access logic at the database level, your application becomes much safer. Just like foreign keys enforce referential integrity, and &lt;a href="https://www.postgresql.org/docs/current/ddl-constraints.html#DDL-CONSTRAINTS-FK" rel="noopener noreferrer"&gt;CASCADE deletes&lt;/a&gt; can be used to enforce data correctness, RLS can enforce authorization on every database query.&lt;/p&gt;

&lt;h2&gt;
  
  
  Expanding access to RLS with Neon RLS
&lt;/h2&gt;

&lt;p&gt;With Authorize, we’re making it easier for developers to use RLS by providing an integration between any authentication provider and Postgres on Neon. After setting it up, calls to the database can be authenticated with a &lt;a href="https://jwt.io/introduction" rel="noopener noreferrer"&gt;JWT&lt;/a&gt; (JSON Web Token) generated by the auth provider, which will be:&lt;/p&gt;

&lt;p&gt;– Verified by the Neon Proxy&lt;/p&gt;

&lt;p&gt;– Added to the request and made available for RLS rules and WHERE clauses alike&lt;/p&gt;

&lt;p&gt;Furthermore, you’ll also have access to a few utility functions such as &lt;code&gt;auth.session()&lt;/code&gt; and &lt;code&gt;auth.user_id()&lt;/code&gt; which will help you use the JWTs that are coming from your auth provider.&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%2Fugnnxtkdh8o81suji8ij.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%2Fugnnxtkdh8o81suji8ij.png" alt="Auth" width="800" height="367"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Any authentication provider is automatically supported by our platform as long as it can generate JWTs and provide some URL for us to download the JWKS.  Here’s an example of using the JWT in a filter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT
    u.name,
    u.email
FROM
    users u
WHERE
    auth.user_id() = u.user_id
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here’s a list of Auth providers we’ve already tested in partnership with each team (more to come): &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;    Clerk – &lt;a href="https://github.com/neondatabase-labs/clerk-nextjs-neon-authorize" rel="noopener noreferrer"&gt;Example Repo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;    Stack Auth – &lt;a href="https://github.com/neondatabase-labs/stack-nextjs-neon-authorize" rel="noopener noreferrer"&gt;Example Repo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;    Auth0 – &lt;a href="https://github.com/neondatabase-labs/auth0-nextjs-neon-authorize" rel="noopener noreferrer"&gt;Example Repo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;    Stytch – &lt;a href="https://github.com/neondatabase-labs/stytch-nextjs-neon-authorize" rel="noopener noreferrer"&gt;Example Repo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;    AWS Cognito – &lt;a href="https://github.com/neondatabase-labs/aws-cognito-express-htmx-neon-authorize" rel="noopener noreferrer"&gt;Example Repo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;    Azure AD – &lt;a href="https://github.com/neondatabase-labs/azure-ad-b2c-nextjs-neon-authorize" rel="noopener noreferrer"&gt;Example Repo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;    Descope Auth – &lt;a href="https://github.com/neondatabase-labs/descope-react-frontend-neon-authorize" rel="noopener noreferrer"&gt;Example Repo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;    Supertokens – &lt;a href="https://github.com/neondatabase-labs/supertokens-nestjs-solidjs-drizzle-neon-authorize" rel="noopener noreferrer"&gt;Example Repo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;    Firebase Auth&lt;/li&gt;
&lt;li&gt;    Keycloak&lt;/li&gt;
&lt;li&gt;    GCP Cloud Identity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Refer to the &lt;a href="https://neon.tech/docs/guides/neon-authorize" rel="noopener noreferrer"&gt;Neon RLS docs&lt;/a&gt; for all the details.&lt;/p&gt;

&lt;h2&gt;
  
  
  The elephant in the room: RLS’s SQL syntax
&lt;/h2&gt;

&lt;p&gt;One of the biggest issues with Postgres RLS is the difficult-to-understand SQL syntax. While LLMs can be great at generating this syntax, it still can easily become too hard to reason about.&lt;/p&gt;

&lt;p&gt;That’s why we’ve partnered with &lt;a href="https://orm.drizzle.team/" rel="noopener noreferrer"&gt;Drizzle ORM&lt;/a&gt; to offer a cleaner, more intuitive way of defining RLS rules. &lt;strong&gt;With Drizzle and Neon, developers can set up RLS policies in a declarative format right alongside their schema definitions.&lt;/strong&gt; This means you can manage RLS in the same place as your schema and data models, making your codebase more organized and easier to maintain.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What if I'm not using Drizzle?&lt;/strong&gt;&lt;br&gt;
That's completely fine: you can still use Neon RLS. Drizzle is not a requirement but an enhancement. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We worked with the Drizzle team in order to design and test both the &lt;code&gt;pgPolicy&lt;/code&gt; function, as well as a &lt;code&gt;crudPolicy&lt;/code&gt; higher-level API that can be used as a helper utility to generate multiple Postgres policies with one function call.&lt;/p&gt;

&lt;p&gt;Here’s a sneak peek of what it looks like to use &lt;code&gt;@drizzle-orm/pg&lt;/code&gt; and &lt;code&gt;@drizzle-orm/neon&lt;/code&gt; together. Also in this repo: &lt;a href="https://github.com/neondatabase-labs/social-wall-drizzle-neon-authorize" rel="noopener noreferrer"&gt;https://github.com/neondatabase-labs/social-wall-drizzle-neon-authorize&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { sql } from "drizzle-orm";
import { pgTable, text, timestamp } from "drizzle-orm/pg-core";
import { authenticatedRole, anonymousRole, crudPolicy, authUid } from "drizzle-orm/neon";



/**
* This defines a simple schema with two tables:
* - users: a table of users
* - posts: a table of social posts
*
* The schema has two RLS policies:
* - users: admin-only
* - posts: anyone can read, authenticated users can modify their own posts
*/




// private table, without RLS policies this is admin-only
export const users = pgTable("users", {
 userId: text("user_id").primaryKey(),
 email: text("email").unique().notNull(),
 createdAt: timestamp("created_at").defaultNow().notNull(),
 updatedAt: timestamp("updated_at").defaultNow().notNull(),
}).enableRLS();


// posts table with RLS policies
// - anyone can read
// - authenticated users can read any post and can modify their own posts
export const posts = pgTable(
 "posts",
 {
   id: text("id").primaryKey(),
   title: text("title").notNull(),
   content: text("content").notNull(),
   userId: text("userId").references(() =&amp;gt; users.userId),
 },
 (table) =&amp;gt; [
   // anyone (anonymous) can read
   crudPolicy({
     role: anonymousRole,
     read: true,
   }),
   // authenticated users can read any post, and modify only their own posts
   crudPolicy({
     role: authenticatedRole,
     read: true,
     // `userId` column matches `auth.user_id()` allows modify
     modify: authUid(table.userId),
   }),
 ],
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this schema, we’re using Postgres for a bunch of different things:&lt;/p&gt;

&lt;p&gt;– Column uniqueness&lt;/p&gt;

&lt;p&gt;– Referential integrity&lt;/p&gt;

&lt;p&gt;– Cascade deletes&lt;/p&gt;

&lt;p&gt;– And with Authorize: access rules!&lt;/p&gt;

&lt;p&gt;Of course, one can also just keep all these rules in “regular application code”. We’re not forcing anyone to use RLS policies. By having authenticated database requests with JWTs, developers can make use of their payloads in &lt;code&gt;WHERE&lt;/code&gt; clauses from their app’s backend as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get started with Neon RLS + Drizzle + Clerk
&lt;/h2&gt;

&lt;p&gt;If you’re using &lt;a href="https://clerk.com/" rel="noopener noreferrer"&gt;Clerk&lt;/a&gt;, we have a &lt;a href="https://neon.tech/docs/guides/neon-authorize-tutorial" rel="noopener noreferrer"&gt;tutorial&lt;/a&gt; to help you get set up quickly, using a sample todos app built with Next.js. Also in this repo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/neondatabase-labs/clerk-nextjs-neon-authorize" rel="noopener noreferrer"&gt;https://github.com/neondatabase-labs/clerk-nextjs-neon-authorize&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What you’ll learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;    How to configure Neon RLS with Clerk for authentication&lt;/li&gt;
&lt;li&gt;    How to set up RLS policies via Drizzle in a clear, declarative way alongside your schema&lt;/li&gt;
&lt;li&gt;    How to test and verify your setup to ensure smooth, secure access control&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;Neon RLS is just the start of our journey towards making application development faster with Postgres. We hope to partner with more authentication providers and ORMs in the future to streamline all of this even more.&lt;/p&gt;

&lt;p&gt;One of the novelties that comes out of this new feature is that you can now develop applications that are entirely client-side without a server/backend. We believe that for simple apps, you can get away with hosting them (for free) on GitHub Pages and then using Neon together with your auth provider of choice, without a backend. However, for more serious projects, we still recommend that you build a backend to protect your database.&lt;/p&gt;

&lt;h2&gt;
  
  
  RLS for everything or not?
&lt;/h2&gt;

&lt;p&gt;Whether to use PG RLS for everything or not is an interesting debate. For the most part, we recommend defining some RLS rules for very important and core authorization logic. For example, &lt;a href="https://neon.tech/blog/multi-tenancy-and-database-per-user-design-in-postgres#shared-schema" rel="noopener noreferrer"&gt;multi-tenant enterprise applications&lt;/a&gt; can definitely benefit from having RLS for extra security. However, it’s probably better to define very intricate access logic in your backend code.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Since all of this is a bit novel, we’re hoping to get a lot of feedback from the community. So, we’ve created a channel for #neon-authorize on our &lt;a href="https://discord.com/invite/92vNTzKDGp" rel="noopener noreferrer"&gt;Discord server&lt;/a&gt;. Please reach out!&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
