<?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: Zak R.</title>
    <description>The latest articles on DEV Community by Zak R. (@zakpie).</description>
    <link>https://dev.to/zakpie</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F555732%2F22c39793-c0c1-474b-a7d5-ac252f757924.png</url>
      <title>DEV Community: Zak R.</title>
      <link>https://dev.to/zakpie</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/zakpie"/>
    <language>en</language>
    <item>
      <title>Stop Juggling Process Managers: Meet pboss, the Runtime-Agnostic Manager for Bun, Deno, and Node.js</title>
      <dc:creator>Zak R.</dc:creator>
      <pubDate>Tue, 06 Oct 2026 21:59:25 +0000</pubDate>
      <link>https://dev.to/zakpie/stop-juggling-process-managers-meet-pboss-the-runtime-agnostic-manager-for-bun-deno-and-nodejs-3fl1</link>
      <guid>https://dev.to/zakpie/stop-juggling-process-managers-meet-pboss-the-runtime-agnostic-manager-for-bun-deno-and-nodejs-3fl1</guid>
      <description>&lt;p&gt;If you're a modern JavaScript or TypeScript developer, you've probably played a little &lt;strong&gt;runtime roulette&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;One legacy project runs on Node.js. Your newer service uses Deno. Another project runs on Bun because you want its performance and built-in tooling.&lt;/p&gt;

&lt;p&gt;The problem isn't choosing a runtime.&lt;/p&gt;

&lt;p&gt;The problem is managing all of them.&lt;/p&gt;

&lt;p&gt;Production tooling often assumes one runtime, which can leave you juggling different process managers, custom scripts, or compatibility layers just to keep your applications running.&lt;/p&gt;

&lt;p&gt;That's the problem the latest version of &lt;strong&gt;ProcBoss (&lt;code&gt;pboss&lt;/code&gt;)&lt;/strong&gt; is designed to solve.&lt;/p&gt;

&lt;h3&gt;
  
  
  One Process Manager. Multiple Runtimes.
&lt;/h3&gt;

&lt;p&gt;The latest ProcBoss update makes it &lt;strong&gt;runtime-agnostic without sacrificing native runtime APIs&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You don't need one process manager for Node.js, another solution for Deno, and something else for Bun.&lt;/p&gt;

&lt;p&gt;You can use a single &lt;code&gt;pboss&lt;/code&gt; installation to manage applications running on all three.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pboss &lt;span class="nt"&gt;--runtime&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;bun start &lt;span class="nt"&gt;--name&lt;/span&gt; bun_server ./bun_server.ts

pboss &lt;span class="nt"&gt;--runtime&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;deno start &lt;span class="nt"&gt;--name&lt;/span&gt; deno_server ./deno_server.ts

pboss &lt;span class="nt"&gt;--runtime&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;node start &lt;span class="nt"&gt;--name&lt;/span&gt; node_server ./node_server.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One process manager.&lt;/p&gt;

&lt;p&gt;Three runtimes.&lt;/p&gt;

&lt;p&gt;One consistent operational workflow.&lt;/p&gt;

&lt;p&gt;And importantly, ProcBoss doesn't force those applications onto the same runtime.&lt;/p&gt;

&lt;h3&gt;
  
  
  Runtime-Agnostic Doesn't Mean "Use Node.js Everywhere"
&lt;/h3&gt;

&lt;p&gt;There are different ways to build a multi-runtime tool.&lt;/p&gt;

&lt;p&gt;The easy approach is to pick one runtime's APIs and build compatibility layers around everything else.&lt;/p&gt;

&lt;p&gt;That wasn't the approach I wanted for ProcBoss.&lt;/p&gt;

&lt;p&gt;Bun, Node.js, and Deno each provide their own native APIs for process management, filesystem access, HTTP servers, and other capabilities.&lt;/p&gt;

&lt;p&gt;ProcBoss uses a &lt;strong&gt;runtime adapter architecture&lt;/strong&gt; to preserve those differences instead of hiding them.&lt;/p&gt;

&lt;p&gt;For process spawning, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Bun       → Bun.spawn
Node.js   → node:child_process
Deno      → Deno.Command
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The core process manager works with capabilities rather than directly depending on one runtime.&lt;/p&gt;

&lt;p&gt;The runtime adapter provides the native implementation.&lt;/p&gt;

&lt;p&gt;So when ProcBoss runs under Bun, it uses Bun's APIs.&lt;/p&gt;

&lt;p&gt;When it runs under Node.js, it uses Node's APIs.&lt;/p&gt;

&lt;p&gt;When it runs under Deno, it uses Deno's APIs.&lt;/p&gt;

&lt;p&gt;There isn't a Node.js compatibility layer sitting between ProcBoss and Bun or Deno.&lt;/p&gt;

&lt;p&gt;That's what makes the runtime-agnostic architecture useful rather than simply being a compatibility wrapper.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Same Applies to Clustering
&lt;/h3&gt;

&lt;p&gt;This is where the update gets particularly interesting.&lt;/p&gt;

&lt;p&gt;A process manager that can start applications across different runtimes is useful.&lt;/p&gt;

&lt;p&gt;A process manager that can &lt;strong&gt;scale those applications using native process capabilities across those runtimes&lt;/strong&gt; is much more useful.&lt;/p&gt;

&lt;p&gt;ProcBoss provides native cluster mode for Bun, Node.js, and Deno.&lt;/p&gt;

&lt;p&gt;You can run multiple instances of an application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pboss start server.ts &lt;span class="nt"&gt;--name&lt;/span&gt; api &lt;span class="nt"&gt;--instances&lt;/span&gt; max
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or specify the number of instances:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pboss start server.ts &lt;span class="nt"&gt;--name&lt;/span&gt; api &lt;span class="nt"&gt;--instances&lt;/span&gt; 4 &lt;span class="nt"&gt;--port&lt;/span&gt; 3000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each instance is a supervised process managed by ProcBoss.&lt;/p&gt;

&lt;p&gt;That means clustering isn't tied to &lt;code&gt;node:cluster&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Instead, ProcBoss uses the appropriate process APIs for the runtime being managed.&lt;/p&gt;

&lt;p&gt;The result is a consistent clustering model across runtimes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scale Without Changing Your Tooling
&lt;/h3&gt;

&lt;p&gt;Suppose you have three applications:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Bun API
Deno API
Node.js API
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;They can all be managed by the same ProcBoss installation.&lt;/p&gt;

&lt;p&gt;You can scale them independently and manage their lifecycles through the same process manager.&lt;/p&gt;

&lt;p&gt;For a running application, you can change its instance count:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pboss scale my-api 8
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And perform a graceful reload:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pboss reload my-api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows workers to be replaced progressively rather than simply killing everything and starting it again.&lt;/p&gt;

&lt;p&gt;The exact behavior depends on the application's runtime and configuration, but the important part is that &lt;strong&gt;the process-management layer remains the same regardless of which JavaScript runtime your application uses.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  It Goes Beyond &lt;code&gt;start&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Runtime support is only part of the update.&lt;/p&gt;

&lt;p&gt;ProcBoss is designed to handle the operational problems that appear once your application is actually running.&lt;/p&gt;

&lt;h3&gt;
  
  
  Namespaces
&lt;/h3&gt;

&lt;p&gt;Group related processes into a namespace and manage them as a unit.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;api
worker
scheduler
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Namespace startup is atomic. If a startup operation fails, ProcBoss can roll back the processes started by that invocation without unnecessarily affecting processes that were already running.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dependencies
&lt;/h3&gt;

&lt;p&gt;Applications often depend on other services.&lt;/p&gt;

&lt;p&gt;An API might depend on PostgreSQL.&lt;/p&gt;

&lt;p&gt;A worker might depend on Redis.&lt;/p&gt;

&lt;p&gt;ProcBoss supports dependency declarations so required dependencies can be resolved before a process starts.&lt;/p&gt;

&lt;p&gt;Dependencies can also refer to external system services rather than only ProcBoss-managed applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  Health Checks
&lt;/h3&gt;

&lt;p&gt;A process being alive doesn't necessarily mean the application is healthy.&lt;/p&gt;

&lt;p&gt;ProcBoss supports health checks so you can monitor whether an application is actually responding, not just whether its process still exists.&lt;/p&gt;

&lt;h3&gt;
  
  
  Logs and Metrics
&lt;/h3&gt;

&lt;p&gt;ProcBoss provides automatic log capture, rotation, retention, compression, real-time log tailing, and Prometheus metrics.&lt;/p&gt;

&lt;p&gt;So the same tool managing the process can also provide the operational information needed to understand it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;ProcBoss provides a &lt;strong&gt;universal installer&lt;/strong&gt; for Linux, macOS, and Windows.&lt;/p&gt;

&lt;h3&gt;
  
  
  Linux and macOS
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://procboss.com/install.sh | sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Windows
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;powershell&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-c&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"irm https://procboss.com/install.ps1 | iex"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The installer lets you select whether ProcBoss should run under &lt;strong&gt;Bun, Node.js, or Deno&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You can also explicitly choose the runtime when needed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pboss &lt;span class="nt"&gt;--runtime&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;bun ...
pboss &lt;span class="nt"&gt;--runtime&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;node ...
pboss &lt;span class="nt"&gt;--runtime&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;deno ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The selected runtime can be persisted locally, and you can change it later with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pboss runtime change
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important distinction is that runtime selection is about &lt;strong&gt;how ProcBoss itself executes&lt;/strong&gt;. The processes it manages can still use their appropriate runtime.&lt;/p&gt;

&lt;p&gt;That is what makes mixed-runtime servers possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Matters
&lt;/h2&gt;

&lt;p&gt;The JavaScript ecosystem no longer revolves around a single runtime.&lt;/p&gt;

&lt;p&gt;That's a good thing.&lt;/p&gt;

&lt;p&gt;Bun, Node.js, and Deno each bring different ideas and capabilities to the ecosystem.&lt;/p&gt;

&lt;p&gt;Developers should be able to choose the runtime that makes sense for a particular project without having to rebuild their production tooling around that decision.&lt;/p&gt;

&lt;p&gt;That's the problem ProcBoss is trying to solve.&lt;/p&gt;

&lt;p&gt;You can have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;project A → Bun
project B → Node.js
project C → Deno
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and still have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    ProcBoss
                       │
          ┌────────────┼────────────┐
          │            │            │
         Bun          Node         Deno
          │            │            │
       native        native       native
        APIs          APIs         APIs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;One process manager. Multiple runtimes. Native APIs.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And because clustering is runtime-aware as well, you don't need a separate scaling solution for each runtime.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;p&gt;ProcBoss started as a Bun process manager.&lt;/p&gt;

&lt;p&gt;The project has now evolved into a runtime-agnostic process manager for modern JavaScript backends.&lt;/p&gt;

&lt;p&gt;The goal isn't to make Bun, Node.js, and Deno behave identically.&lt;/p&gt;

&lt;p&gt;It's to give them a consistent operational layer &lt;strong&gt;without taking away what makes each runtime different.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you're running applications across multiple JavaScript runtimes, you can now manage them with one &lt;code&gt;pboss&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Learn more
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;📥 &lt;a href="https://docs.procboss.com/installation/" rel="noopener noreferrer"&gt;Installation Guide&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;⚙️ &lt;a href="https://docs.procboss.com/runtimes/" rel="noopener noreferrer"&gt;Supported Runtimes &amp;amp; Native APIs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;⚡ &lt;a href="https://docs.procboss.com/cli/processes/" rel="noopener noreferrer"&gt;Process Management&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;📈 &lt;a href="https://docs.procboss.com/cli/cluster/" rel="noopener noreferrer"&gt;Cluster Mode&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Have you been running different process-management tools for different JavaScript runtimes? I'd be interested to hear how you're handling mixed-runtime deployments.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>deno</category>
      <category>node</category>
      <category>pm2</category>
      <category>bunjs</category>
    </item>
    <item>
      <title>The Era of Scary Cron Syntax Is Over: Meet pboss cron</title>
      <dc:creator>Zak R.</dc:creator>
      <pubDate>Fri, 18 Sep 2026 01:37:31 +0000</pubDate>
      <link>https://dev.to/zakpie/the-era-of-scary-cron-syntax-is-over-meet-pboss-cron-15m3</link>
      <guid>https://dev.to/zakpie/the-era-of-scary-cron-syntax-is-over-meet-pboss-cron-15m3</guid>
      <description>&lt;p&gt;You know the feeling. You need to run a backup script every day at 9:11am, so you open a terminal, type &lt;code&gt;crontab -e&lt;/code&gt;, and stare at a blinking cursor waiting for you to conjure five asterisks and numbers in the correct ancient order.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;11 9 * * *
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Is that minute-then-hour, or hour-then-minute? Did you just schedule this for 9:11am or for the 9th minute of every hour that happens to also be... you get the idea. You copy-paste it into an online cron parser to check your own work. You feel bad about it. We all feel bad about it.&lt;/p&gt;

&lt;p&gt;Cron syntax is one of those things every backend developer has "learned" a dozen times and forgotten a dozen times, because there's zero semantic connection between what you type and what it means. &lt;code&gt;*/15 * * * *&lt;/code&gt; doesn't &lt;em&gt;look&lt;/em&gt; like "every 15 minutes" — it looks like line noise that happens to work.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pboss&lt;/code&gt; — the Bun-powered process manager — ships a cron system that fixes this without throwing away the power of raw cron when you actually need it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem with &lt;code&gt;crontab -e&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Standard cron has a few real, practical downsides beyond "the syntax is opaque":&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No persistence layer of its own.&lt;/strong&gt; It's a system-level daemon, separate from whatever's managing your app processes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No visibility.&lt;/strong&gt; Want to know when a job last ran, whether it succeeded, or when it's running next? Better go dig through &lt;code&gt;/var/log&lt;/code&gt; or set up your own logging by hand.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No easy one-shot scheduling.&lt;/strong&gt; Need something to run once, next Tuesday at 11pm, and never again? You're writing a workaround, not using cron the way it was designed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Machine downtime silently eats jobs&lt;/strong&gt;, and figuring out what got skipped is a manual, aggravating exercise.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're already running &lt;code&gt;pboss&lt;/code&gt; to manage your app processes, none of this needs to be a separate problem you solve separately.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enter human-readable schedules
&lt;/h2&gt;

&lt;p&gt;Here's the same 9:11am backup job in &lt;code&gt;pboss&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pboss cron run everyday@9:11 &lt;span class="s2"&gt;"bun /srv/backup.ts"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Read that out loud. It says exactly what it does. No mental math, no lookup table, no "wait, is Sunday 0 or 7 in this implementation."&lt;/p&gt;

&lt;p&gt;A few more, so you get the shape of the grammar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Every Sunday at 10:10am, named explicitly&lt;/span&gt;
pboss cron run every-sunday@10:10 &lt;span class="s2"&gt;"sh /srv/cleanup.sh"&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; cleanup

&lt;span class="c"&gt;# One-shot: fires once, at a specific date and time, then it's done&lt;/span&gt;
pboss cron run on-date@24-10-2026-23:10 &lt;span class="s2"&gt;"node migrate.js"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The grammar covers the cases you actually hit in real projects:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;You want...&lt;/th&gt;
&lt;th&gt;You write...&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Every day at midnight&lt;/td&gt;
&lt;td&gt;&lt;code&gt;everyday&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Every day at a specific time&lt;/td&gt;
&lt;td&gt;&lt;code&gt;everyday@9:11&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Every N seconds&lt;/td&gt;
&lt;td&gt;&lt;code&gt;every-15-seconds&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Every hour, or every hour at :30&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;everyhour&lt;/code&gt; / &lt;code&gt;everyhour@30&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Every week on a given weekday&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;every-sunday@10:10&lt;/code&gt;, &lt;code&gt;everyMonday@10:10&lt;/code&gt;, &lt;code&gt;onSunday@23:10&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Every month, or a specific day of month&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;everymonth&lt;/code&gt; / &lt;code&gt;every-15th@10:10&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Every N hours or N days&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;every-6-hours&lt;/code&gt; / &lt;code&gt;every-2-days@8&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Once, later today or tomorrow&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;today@23:10&lt;/code&gt; / &lt;code&gt;tomorrow@8:00&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Once, on a specific calendar date&lt;/td&gt;
&lt;td&gt;&lt;code&gt;on-date@24-10-2026-23:10&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A couple of details that show this was designed by someone who's actually been burned by cron before:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hour 24 rolls to the next day.&lt;/strong&gt; &lt;code&gt;everyday@24:30&lt;/code&gt; means 00:30 tomorrow, so you can express "half an hour after midnight" without the off-by-one anxiety.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keywords are forgiving.&lt;/strong&gt; &lt;code&gt;on-date@&lt;/code&gt;, &lt;code&gt;onDate@&lt;/code&gt;, and &lt;code&gt;on_date@&lt;/code&gt; are all the same thing — hyphens, underscores, and camelCase are interchangeable, so you don't have to remember one exact casing convention.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dates are calendar-validated.&lt;/strong&gt; Try to schedule &lt;code&gt;on-date@31-02-2026&lt;/code&gt; and you get a clear rejection instead of a job that silently never fires.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A past &lt;code&gt;today@…&lt;/code&gt; time gets rejected with a suggestion&lt;/strong&gt;, not silently scheduled into a black hole.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Missed jobs are skipped, not queued up.&lt;/strong&gt; If the daemon or machine was down, a recurring job just reschedules to its next real future occurrence — same behavior you'd expect from classic cron, so nothing runs in a confusing backlog burst when the box comes back up.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The escape hatch: raw cron still works
&lt;/h2&gt;

&lt;p&gt;This is the part that matters most, honestly. Nobody wants a "friendly" tool that boxes you in the moment your schedule gets weird. So &lt;code&gt;pboss&lt;/code&gt; doesn't replace cron expressions — it &lt;em&gt;accepts&lt;/em&gt; them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pboss cron run &lt;span class="s2"&gt;"*/5 * * * *"&lt;/span&gt; &lt;span class="s2"&gt;"curl -s https://example.com/ping"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can even go beyond standard 5-field cron with a 6-field expression, where the first field is seconds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pboss cron run &lt;span class="s2"&gt;"*/10 * * * * *"&lt;/span&gt; &lt;span class="s2"&gt;"node heartbeat.js"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the mental model is: reach for the friendly syntax by default, and drop into raw cron only for the genuinely gnarly schedules where a plain-English phrase can't capture what you need.&lt;/p&gt;

&lt;h2&gt;
  
  
  Managing jobs like they're first-class citizens
&lt;/h2&gt;

&lt;p&gt;Because cron jobs live in the daemon itself (persisted to &lt;code&gt;~/.pboss/cron.json&lt;/code&gt;, surviving reboots), you get the same kind of visibility you'd expect for a managed process:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pboss cron list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌────┬─────────┬─────────────┬──────────────────┬───────────────────────────┬──────┬──────┬──────────┐
│ id │ name    │ schedule    │ command          │ next run                  │ runs │ last │ status   │
├────┼─────────┼─────────────┼──────────────────┼───────────────────────────┼──────┼──────┼──────────┤
│  1 │ backup  │ everyday@9  │ bun backup.ts    │ 2026-09-07 09:00 Mon      │   14 │ ✓    │ ● online │
│  2 │ cleanup │ every-sunday│ sh cleanup.sh    │ 2026-09-13 00:00 Sun      │    3 │ ✓    │ ● online │
└────┴─────────┴─────────────┴──────────────────┴───────────────────────────┴──────┴──────┴──────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Peek at upcoming runs without waiting around:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pboss cron next backup &lt;span class="nt"&gt;--count&lt;/span&gt; 5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Force a run right now, without touching the schedule:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pboss cron trigger backup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And clean up when a job's done:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pboss cron remove backup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every run gets logged automatically to &lt;code&gt;~/.pboss/logs/cron/&amp;lt;name&amp;gt;.log&lt;/code&gt;, with a header (job name, schedule, working directory), the command's full combined output, and a footer with exit code and duration. That's debugging information you'd otherwise have to wire up yourself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Declaring crons alongside your apps
&lt;/h2&gt;

&lt;p&gt;If you're already using an ecosystem file to manage your processes, cron jobs slot right in next to them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;crons&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="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;backup&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;schedule&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;everyday@2:00&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bun /srv/backup.ts&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="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;report&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;schedule&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;every-15th@10:10&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sh /srv/report.sh&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;// paused until you're ready&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;maintenance&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;schedule&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;every-sunday@5:00&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sh /srv/maintenance.sh&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&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="na"&gt;apps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="cm"&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;Re-running the ecosystem file updates schedules in place — jobs are matched by name, so you can tweak a schedule and redeploy without duplicating jobs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Or drive it all from code
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&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;pboss&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;pboss&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;job&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;pboss&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cronAdd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;everyday@9:11&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bun backup.ts&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;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;backup&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;pboss&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cronJobs&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; — &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; (runs: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;runCount&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;)`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;pboss&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cronTrigger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;backup&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// run now&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;pboss&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cronRemove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;backup&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;    &lt;span class="c1"&gt;// remove&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Under the hood
&lt;/h2&gt;

&lt;p&gt;Jobs execute through the system shell (&lt;code&gt;/bin/sh -c&lt;/code&gt; on Unix, &lt;code&gt;cmd /c&lt;/code&gt; on Windows), so pipes and redirects behave exactly like you'd expect:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pboss cron run everyday@3 &lt;span class="s2"&gt;"bun report.ts | mail -s 'daily report' ops@example.com"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the scheduler itself isn't naively polling every minute and hoping — it sleeps until the next actual scheduled run with a periodic watchdog rescan, so timing stays accurate to the second even across clock adjustments.&lt;/p&gt;

&lt;h2&gt;
  
  
  The takeaway
&lt;/h2&gt;

&lt;p&gt;Cron syntax isn't going anywhere — it's load-bearing infrastructure for the entire internet, and &lt;code&gt;pboss&lt;/code&gt; doesn't pretend otherwise; raw expressions are still a first-class option. But for the 90% of scheduling you actually do — "run this every day," "run this every Sunday morning," "run this once, next Tuesday" — there's no reason to keep translating your intent into five cryptic fields by hand.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pboss cron run everyday@9:11 &lt;span class="s2"&gt;"bun /srv/backup.ts"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. That's the whole horror story, and it has a happy ending.&lt;/p&gt;




&lt;p&gt;Want to try it:  check the &lt;a href="https://docs.procboss.com/cli/cron/" rel="noopener noreferrer"&gt;cron docs&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>cron</category>
      <category>pboss</category>
      <category>node</category>
    </item>
    <item>
      <title>Stellar AppKit: Building a Complete Application Layer for Stellar</title>
      <dc:creator>Zak R.</dc:creator>
      <pubDate>Thu, 27 Aug 2026 08:47:28 +0000</pubDate>
      <link>https://dev.to/zakpie/stellar-appkit-building-a-complete-application-layer-for-stellar-4d10</link>
      <guid>https://dev.to/zakpie/stellar-appkit-building-a-complete-application-layer-for-stellar-4d10</guid>
      <description>&lt;p&gt;Building a Stellar application shouldn't require developers to assemble a dozen different pieces before they can get to the product itself.&lt;/p&gt;

&lt;p&gt;Wallet connectivity is only the beginning.&lt;/p&gt;

&lt;p&gt;A production-grade Stellar application needs to handle wallet integration, responsive wallet UX, authentication, session management, Soroban transactions, transaction simulation, error handling, localization, and increasingly, compliance and user onboarding.&lt;/p&gt;

&lt;p&gt;That is the problem we're trying to solve with &lt;strong&gt;Stellar AppKit&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Stellar AppKit is an application SDK designed to provide a unified layer between your application, your users, wallets, and the Stellar network.&lt;/p&gt;

&lt;p&gt;The easiest way to think about it is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Wallet connectivity gets a user into your application. AppKit is focused on everything that happens around that connection.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What is Stellar AppKit?
&lt;/h2&gt;

&lt;p&gt;Stellar AppKit started as a wallet connectivity library, but the project has evolved into something broader.&lt;/p&gt;

&lt;p&gt;The goal is to provide developers with reusable infrastructure for the application layer of Stellar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Your Application
       │
       ▼
┌──────────────────────┐
│    Stellar AppKit    │
├──────────────────────┤
│ Wallet Connectivity  │
│ Authentication       │
│ Session Management   │
│ Transaction UX       │
│ Soroban Infrastructure│
│ Risk Detection       │
│ Localization         │
│ Compliance           │
└──────────┬───────────┘
           │
           ▼
   Stellar Ecosystem
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of every application independently implementing these primitives, AppKit aims to provide them through one consistent developer experience.&lt;/p&gt;




&lt;h2&gt;
  
  
  Wallet connectivity is only the starting point
&lt;/h2&gt;

&lt;p&gt;There are already good wallet connectivity solutions in the Stellar ecosystem.&lt;/p&gt;

&lt;p&gt;Stellar Wallets Kit, for example, solves an important problem: connecting applications to multiple Stellar wallets through a common interface.&lt;/p&gt;

&lt;p&gt;We don't see that problem as the entire application stack.&lt;/p&gt;

&lt;p&gt;A developer building a real application eventually has to answer questions like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How should the wallet selector behave on mobile?&lt;/li&gt;
&lt;li&gt;How do I support multiple frontend frameworks?&lt;/li&gt;
&lt;li&gt;How do I localize the wallet experience?&lt;/li&gt;
&lt;li&gt;How do I authenticate a user with their wallet?&lt;/li&gt;
&lt;li&gt;How do I maintain their session?&lt;/li&gt;
&lt;li&gt;How do I validate that authentication on the server?&lt;/li&gt;
&lt;li&gt;How do I simulate a Soroban transaction before signing?&lt;/li&gt;
&lt;li&gt;How do I show the user what they're actually signing?&lt;/li&gt;
&lt;li&gt;How do I detect potentially dangerous transactions?&lt;/li&gt;
&lt;li&gt;How do I onboard users who don't already have a wallet?&lt;/li&gt;
&lt;li&gt;How do I handle compliance requirements?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AppKit is intended to address that larger set of problems.&lt;/p&gt;




&lt;h2&gt;
  
  
  A better wallet UX
&lt;/h2&gt;

&lt;p&gt;Wallet connectivity APIs are useful, but the user experience surrounding a wallet connection matters just as much.&lt;/p&gt;

&lt;p&gt;A desktop application and a mobile application shouldn't necessarily present wallet selection in the same way.&lt;/p&gt;

&lt;p&gt;AppKit supports different UI presentation patterns, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Desktop modal&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mobile bottom sheet&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Inline and UI-agnostic flows&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This allows applications to use AppKit's ready-made experience or build their own interface around the underlying SDK.&lt;/p&gt;

&lt;p&gt;The objective isn't to force a specific design.&lt;/p&gt;

&lt;p&gt;It is to give developers a good default experience while keeping the underlying functionality flexible.&lt;/p&gt;




&lt;h2&gt;
  
  
  25 languages out of the box
&lt;/h2&gt;

&lt;p&gt;Stellar is a global ecosystem, so localization shouldn't become another project developers have to maintain themselves.&lt;/p&gt;

&lt;p&gt;AppKit currently supports &lt;strong&gt;25 languages&lt;/strong&gt;, including Chinese and other major languages.&lt;/p&gt;

&lt;p&gt;That means wallet-related interfaces, authentication flows, and other AppKit components can be presented to users in their preferred language without every application having to implement the translation infrastructure independently.&lt;/p&gt;

&lt;p&gt;Localization is treated as part of the application experience rather than an afterthought.&lt;/p&gt;




&lt;h2&gt;
  
  
  Multi-framework support
&lt;/h2&gt;

&lt;p&gt;Another important design decision is keeping AppKit independent from a single frontend framework.&lt;/p&gt;

&lt;p&gt;The core SDK is framework-agnostic, while UI integrations are available for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;React&lt;/li&gt;
&lt;li&gt;Vue&lt;/li&gt;
&lt;li&gt;Svelte&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We're also working toward support for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;React Native&lt;/li&gt;
&lt;li&gt;LynxJS&lt;/li&gt;
&lt;li&gt;Flutter&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The objective is to make AppKit useful across both web and mobile applications while maintaining the same underlying concepts and developer experience.&lt;/p&gt;

&lt;p&gt;A developer shouldn't have to completely rethink wallet and authentication infrastructure just because their frontend stack changed.&lt;/p&gt;




&lt;h2&gt;
  
  
  Transaction UX: don't make users sign blind XDR
&lt;/h2&gt;

&lt;p&gt;One of the areas we're particularly interested in is &lt;strong&gt;transaction understanding&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Traditionally, an application builds a transaction, produces XDR, and asks a wallet to sign it.&lt;/p&gt;

&lt;p&gt;From the user's perspective, that can be extremely opaque.&lt;/p&gt;

&lt;p&gt;The user may be asked to approve a transaction without having a clear understanding of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which operations are being executed&lt;/li&gt;
&lt;li&gt;Which assets are moving&lt;/li&gt;
&lt;li&gt;How balances will change&lt;/li&gt;
&lt;li&gt;What fees are involved&lt;/li&gt;
&lt;li&gt;Which contracts are being called&lt;/li&gt;
&lt;li&gt;Whether there are potential risks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AppKit is designed to put an interpretation layer around transactions.&lt;/p&gt;

&lt;p&gt;The vision is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Transaction
     │
     ▼
Decode
     │
     ▼
Simulate
     │
     ▼
Explain
     │
     ▼
Assess Risk
     │
     ▼
User Approval
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This includes capabilities around transaction previews, operation decoding, simulation, balance and fee information, contract information, and risk detection.&lt;/p&gt;

&lt;p&gt;The goal is simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Users should have a much better understanding of what they are signing.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Soroban application infrastructure
&lt;/h2&gt;

&lt;p&gt;Soroban introduces another layer of complexity.&lt;/p&gt;

&lt;p&gt;A typical transaction flow isn't simply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create → Sign → Submit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Applications often need to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Build
  ↓
Simulate
  ↓
Prepare
  ↓
Sign
  ↓
Submit
  ↓
Track
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;AppKit provides abstractions around this lifecycle so developers can work with higher-level APIs instead of rebuilding the same workflow in every project.&lt;/p&gt;

&lt;p&gt;We're also working on capabilities such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Typed contract clients&lt;/li&gt;
&lt;li&gt;Transaction helpers&lt;/li&gt;
&lt;li&gt;RPC failover&lt;/li&gt;
&lt;li&gt;Simulation-aware execution&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is to make interacting with Soroban feel more like using an application SDK and less like manually orchestrating every transaction step.&lt;/p&gt;




&lt;h2&gt;
  
  
  Authentication shouldn't stop at "Connect Wallet"
&lt;/h2&gt;

&lt;p&gt;A wallet connection does not necessarily mean the user is authenticated in your application.&lt;/p&gt;

&lt;p&gt;Modern applications usually need a proper authentication lifecycle.&lt;/p&gt;

&lt;p&gt;AppKit is building &lt;strong&gt;Stellar authentication and session management inspired by Sign In with Ethereum (SIWE)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The system is designed around concepts 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;Connect Wallet
      ↓
Request Nonce
      ↓
Sign Authentication Message
      ↓
Server Validation
      ↓
Create Session
      ↓
Authenticated Application
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Nonce-based authentication&lt;/li&gt;
&lt;li&gt;Signed authentication messages&lt;/li&gt;
&lt;li&gt;Session creation&lt;/li&gt;
&lt;li&gt;Session persistence&lt;/li&gt;
&lt;li&gt;Re-authentication&lt;/li&gt;
&lt;li&gt;Sign-out&lt;/li&gt;
&lt;li&gt;Server-side signature and session validation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is to make a Stellar wallet usable as an application identity rather than treating wallet connection as the authentication mechanism itself.&lt;/p&gt;




&lt;h2&gt;
  
  
  Walletless onboarding
&lt;/h2&gt;

&lt;p&gt;One of the bigger areas on our roadmap is &lt;strong&gt;walletless connectivity&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Crypto onboarding can be a significant barrier for users who have never interacted with a wallet before.&lt;/p&gt;

&lt;p&gt;We're working toward allowing applications to onboard users through more familiar authentication methods.&lt;/p&gt;

&lt;h2&gt;
  
  
  Social login
&lt;/h2&gt;

&lt;p&gt;Applications will be able to offer familiar social authentication flows so users can get started without first installing and configuring a traditional crypto wallet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Passkeys
&lt;/h2&gt;

&lt;p&gt;We're also working toward passkey-based authentication, allowing users to authenticate using device-native credentials and biometrics.&lt;/p&gt;

&lt;p&gt;The broader goal is to make Stellar applications accessible to users who don't already identify themselves as "crypto users."&lt;/p&gt;

&lt;p&gt;Instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Install wallet
↓
Create account
↓
Find recovery phrase
↓
Connect wallet
↓
Start application
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the experience can move closer to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Authenticate
↓
Start using the application
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;while still allowing applications to interact with Stellar underneath.&lt;/p&gt;




&lt;h2&gt;
  
  
  Compliance and KYC
&lt;/h2&gt;

&lt;p&gt;Another area we're exploring is making compliance infrastructure available directly at the application layer.&lt;/p&gt;

&lt;p&gt;For many Stellar applications, particularly those involving regulated assets, real-world assets, financial services, or restricted jurisdictions, compliance can't simply be an external concern.&lt;/p&gt;

&lt;p&gt;Developers may need to know whether a user:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Has completed KYC&lt;/li&gt;
&lt;li&gt;Is eligible to use a particular application&lt;/li&gt;
&lt;li&gt;Is from an allowed jurisdiction&lt;/li&gt;
&lt;li&gt;Meets an age requirement&lt;/li&gt;
&lt;li&gt;Satisfies another compliance policy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Today, developers often have to assemble separate identity and compliance systems to handle these requirements.&lt;/p&gt;

&lt;p&gt;We're working toward allowing developers to request and manage KYC directly through AppKit.&lt;/p&gt;

&lt;h2&gt;
  
  
  A zero-knowledge compliance layer
&lt;/h2&gt;

&lt;p&gt;The longer-term vision is to combine compliance verification with zero-knowledge technology.&lt;/p&gt;

&lt;p&gt;Instead of putting sensitive personal information on-chain, applications could verify specific properties about a user.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;KYC completed      → ✓
Allowed jurisdiction → ✓
Age requirement    → ✓
Restricted status   → ✗
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;without exposing the underlying personal information directly on-chain.&lt;/p&gt;

&lt;p&gt;The objective is to make compliance:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Verifiable + Privacy-preserving + Reusable&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is still an area we're actively developing, but we believe it could become increasingly important as Stellar applications move into regulated and real-world use cases.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why not just use a wallet SDK?
&lt;/h2&gt;

&lt;p&gt;This is probably the most important distinction.&lt;/p&gt;

&lt;p&gt;If your application only needs to connect to a Stellar wallet, a wallet-focused SDK may be exactly what you need.&lt;/p&gt;

&lt;p&gt;AppKit is intended for applications that need more.&lt;/p&gt;

&lt;p&gt;The difference can be summarized like this:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Wallet Connectivity&lt;/th&gt;
&lt;th&gt;Application Layer&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Connect wallet&lt;/td&gt;
&lt;td&gt;Connect wallet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sign transaction&lt;/td&gt;
&lt;td&gt;Sign transaction&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Wallet selection&lt;/td&gt;
&lt;td&gt;Wallet UX&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Wallet abstraction&lt;/td&gt;
&lt;td&gt;Authentication&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Session management&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Server-side validation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Transaction preview&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Simulation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Risk detection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Soroban lifecycle&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Localization&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Cross-framework UI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Walletless onboarding&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Compliance infrastructure&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;We don't think developers need yet another abstraction simply for the sake of having one.&lt;/p&gt;

&lt;p&gt;The goal is to reduce the amount of application infrastructure they have to build repeatedly.&lt;/p&gt;




&lt;h2&gt;
  
  
  The bigger vision
&lt;/h2&gt;

&lt;p&gt;The long-term vision for AppKit is a single application layer that helps developers move through the entire user and transaction lifecycle:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    ┌───────────────┐
                    │     User      │
                    └───────┬───────┘
                            │
                            ▼
                  ┌──────────────────┐
                  │   Authentication │
                  └────────┬─────────┘
                           │
                           ▼
                  ┌──────────────────┐
                  │     Session      │
                  └────────┬─────────┘
                           │
                           ▼
                  ┌──────────────────┐
                  │ Wallet / Identity│
                  └────────┬─────────┘
                           │
                           ▼
                  ┌──────────────────┐
                  │    Transaction   │
                  │ Preview / Risk   │
                  └────────┬─────────┘
                           │
                           ▼
                  ┌──────────────────┐
                  │      Soroban     │
                  │    Execution     │
                  └────────┬─────────┘
                           │
                           ▼
                  ┌──────────────────┐
                  │     Stellar      │
                  └──────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And eventually, developers should be able to choose between traditional wallets, smart wallets, social authentication, passkeys, and compliant identity flows without having to completely rewrite their application.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's next?
&lt;/h2&gt;

&lt;p&gt;We're continuing to build AppKit around the needs of Stellar developers.&lt;/p&gt;

&lt;p&gt;Some of the areas we're working on include:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Walletless authentication&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Social login&lt;/li&gt;
&lt;li&gt;Passkeys&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cross-platform&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;React Native&lt;/li&gt;
&lt;li&gt;LynxJS&lt;/li&gt;
&lt;li&gt;Flutter&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Compliance&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Integrated KYC flows&lt;/li&gt;
&lt;li&gt;Zero-knowledge-based compliance verification&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Application infrastructure&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;More transaction intelligence&lt;/li&gt;
&lt;li&gt;More Soroban abstractions&lt;/li&gt;
&lt;li&gt;More wallet integrations&lt;/li&gt;
&lt;li&gt;Improved developer tooling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal isn't to build the biggest SDK possible.&lt;/p&gt;

&lt;p&gt;It's to make building a Stellar application significantly easier.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Stellar already has strong infrastructure for wallets, assets, payments, and smart contracts.&lt;/p&gt;

&lt;p&gt;What we're building with &lt;strong&gt;Stellar AppKit&lt;/strong&gt; is the layer around those primitives.&lt;/p&gt;

&lt;p&gt;A developer shouldn't have to independently solve wallet UX, authentication, session management, transaction interpretation, Soroban execution, localization, and eventually compliance every time they start a new Stellar application.&lt;/p&gt;

&lt;p&gt;The vision is straightforward:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Connect → Authenticate → Understand → Sign → Execute → Verify&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's what we're building with Stellar AppKit.&lt;/p&gt;

&lt;p&gt;The project is open source, and we're actively looking for feedback from developers building on Stellar.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/SagantaHQ/stellar-appkit" rel="noopener noreferrer"&gt;https://github.com/SagantaHQ/stellar-appkit&lt;/a&gt;&lt;/p&gt;

</description>
      <category>stellar</category>
      <category>wallet</category>
      <category>blockchain</category>
      <category>web3</category>
    </item>
    <item>
      <title>Why I Stopped Using PM2 and Built My Own Bun Process Manager</title>
      <dc:creator>Zak R.</dc:creator>
      <pubDate>Thu, 12 Feb 2026 15:11:08 +0000</pubDate>
      <link>https://dev.to/zakpie/why-i-stopped-using-pm2-and-built-my-own-bun-process-manager-4ehe</link>
      <guid>https://dev.to/zakpie/why-i-stopped-using-pm2-and-built-my-own-bun-process-manager-4ehe</guid>
      <description>&lt;p&gt;&lt;strong&gt;I loved PM2. Then I switched to Bun.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let me tell you a quick story. Six months ago, I migrated a handful of microservices from Node to Bun. The speed improvements were everything the benchmarks promised. Cold starts dropped dramatically. Memory usage shrank. I was thrilled.&lt;/p&gt;

&lt;p&gt;Then I noticed something. My process manager, PM2, the tool I'd relied on for years, was now the slowest part of my stack. It was the thing consuming the most memory in some cases. The irony of running a Node-based supervisor over hyper-optimized Bun processes started to eat at me.&lt;/p&gt;

&lt;p&gt;So I did what any reasonable developer does. I spent my weekends building a replacement.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Breaking Point
&lt;/h2&gt;

&lt;p&gt;The final straw wasn't one big thing. It was a cascade of small frustrations. PM2 would occasionally misreport memory usage for Bun processes. The TypeScript integration required extra flags and workarounds. &lt;/p&gt;

&lt;p&gt;I had to maintain a separate ecosystem.json that felt increasingly disconnected from the rest of my Bun-native tooling. Every time I ran &lt;strong&gt;pm2 start&lt;/strong&gt;, there was a visible delay as the Node-based daemon spun up, only to then launch a Bun process.&lt;/p&gt;

&lt;p&gt;I started keeping a list of these friction points. After a few weeks, the list was long enough to justify a project.&lt;/p&gt;

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

&lt;p&gt;ProcBoss (pboss) is a process manager that does one thing: manage long-running Bun processes without any Node dependency. &lt;/p&gt;

&lt;p&gt;No daemon running on a separate runtime. No compatibility layers. Just Bun managing Bun.&lt;/p&gt;

&lt;p&gt;The CLI is deliberately familiar:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;bun i -g pboss&lt;br&gt;
pboss start server.ts --name api&lt;br&gt;
pboss restart api&lt;br&gt;
pboss logs api --lines 100&lt;br&gt;
pboss list&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Under the hood, everything uses Bun's native APIs. Subprocess spawning uses Bun.spawn. File operations use Bun.write and Bun.file. &lt;/p&gt;

&lt;p&gt;The internal state management uses Bun's built-in SQLite. No fs polyfills. No child_process from Node. Pure Bun.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Results
&lt;/h2&gt;

&lt;p&gt;After migrating my services from PM2 to ProcBoss (pboss), here's what I noticed.&lt;br&gt;
The process manager itself starts almost instantly. &lt;/p&gt;

&lt;p&gt;There's no daemon boot delay. The memory overhead of the manager dropped significantly because it's not running a full Node runtime alongside Bun. &lt;/p&gt;

&lt;p&gt;TypeScript files just work — no flags, no config, no transpilation. And the whole thing feels coherent in a way that's hard to describe. My entire stack is one runtime now, top to bottom.&lt;/p&gt;

&lt;h2&gt;
  
  
  Should You Switch?
&lt;/h2&gt;

&lt;p&gt;If you're running Node services, PM2 is still excellent. Seriously. It's mature, battle-tested, and feature-rich.&lt;/p&gt;

&lt;p&gt;But if you've committed to Bun, consider whether your toolchain has actually caught up with that decision. Your runtime is Bun. Your package manager is Bun. Your test runner is Bun. Why is your process manager still Node?&lt;/p&gt;

&lt;p&gt;That's the question that led me to build ProcBoss (pboss). Maybe it's the question you've been ignoring too.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links&lt;/strong&gt;&lt;br&gt;
Repository: &lt;a&gt;https://github.com/procboss/pboss&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Package: &lt;a href="https://www.npmjs.com/package/pboss" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/pboss&lt;/a&gt;&lt;/p&gt;

</description>
      <category>bunjs</category>
      <category>pm2</category>
      <category>procboss</category>
      <category>pboss</category>
    </item>
    <item>
      <title>Deploying Solana Anchor Programs Easily with Rocket Anchor</title>
      <dc:creator>Zak R.</dc:creator>
      <pubDate>Mon, 10 Nov 2025 23:50:06 +0000</pubDate>
      <link>https://dev.to/zakpie/deploying-solana-anchor-programs-easily-with-rocket-anchor-48jf</link>
      <guid>https://dev.to/zakpie/deploying-solana-anchor-programs-easily-with-rocket-anchor-48jf</guid>
      <description>&lt;p&gt;If you're a developer working with Anchor on Solana, you know the drill. You build your powerful program, and then... you're stuck writing a tangled mess of ad-hoc scripts for deployment, upgrades, and account initialization. It's time-consuming, error-prone, and just plain frustrating.&lt;/p&gt;

&lt;p&gt;What if you could have a smooth, repeatable, Hardhat-style workflow?&lt;/p&gt;

&lt;p&gt;Meet &lt;strong&gt;&lt;a href="https://www.npmjs.com/package/rocket-anchor" rel="noopener noreferrer"&gt;Rocket Anchor&lt;/a&gt;&lt;/strong&gt;, a new open-source tool designed to save you from deployment headaches and streamline your entire process. This guide will walk you through exactly what it is and how to get started.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Rocket Anchor?
&lt;/h2&gt;

&lt;p&gt;Rocket Anchor is a CLI and programmatic tool that brings the developer-friendly experience of tools like Hardhat to the Anchor ecosystem.&lt;/p&gt;

&lt;p&gt;Its main goal is to solve the "last mile" problem of Anchor development:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;It replaces manual scripts&lt;/strong&gt; with a clean, config-based CLI workflow.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It introduces "seeding,"&lt;/strong&gt; a powerful concept for initializing accounts, PDAs, and program state right after deployment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It's built for teams,&lt;/strong&gt; making it easy to manage deployments across different networks (&lt;code&gt;devnet&lt;/code&gt;, &lt;code&gt;mainnet&lt;/code&gt;) without changing your code.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Key Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hardhat-Inspired CLI:&lt;/strong&gt; Get a familiar workflow with commands like &lt;code&gt;init&lt;/code&gt;, &lt;code&gt;deploy&lt;/code&gt;, and &lt;code&gt;seed&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Powerful Seeding:&lt;/strong&gt; Run scripts &lt;em&gt;after&lt;/em&gt; deployment to initialize program state, create PDAs, or set up initial data. This is a massive time-saver.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network Management:&lt;/strong&gt; Easily configure different networks (like &lt;code&gt;devnet&lt;/code&gt;, &lt;code&gt;testnet&lt;/code&gt;, &lt;code&gt;mainnet&lt;/code&gt;, &lt;code&gt;custom-network&lt;/code&gt;) in a single config file, complete with RPC endpoints and keypair paths.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Programmatic API:&lt;/strong&gt; Need to integrate Rocket Anchor into your existing TypeScript toolchain? You can import and use it directly.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;You can install Rocket Anchor globally to use it as a CLI tool across all your projects, or locally as a &lt;code&gt;devDependency&lt;/code&gt; in a specific project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Global Install:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Local Install:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; rocket-anchor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Getting Started: Your First Deployment
&lt;/h2&gt;

&lt;p&gt;Let's walk through the entire workflow from zero to a seeded deployment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Initialize Rocket Anchor
&lt;/h3&gt;

&lt;p&gt;In the root of your Anchor project, run the &lt;code&gt;init&lt;/code&gt; command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx ra init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create a new file named &lt;code&gt;ra.config.ts&lt;/code&gt; in your project's root. This is where you'll define all your networks and deployment configurations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Configure Your Networks
&lt;/h3&gt;

&lt;p&gt;Open the newly created &lt;code&gt;ra.config.ts&lt;/code&gt;. This is where you'll tell Rocket Anchor how to connect to different Solana clusters.&lt;/p&gt;

&lt;p&gt;A typical configuration might look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ra.config.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;RocketAnchorConfig&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;rocket-anchor&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;RocketAnchorConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Local validator&lt;/span&gt;
    &lt;span class="na"&gt;localnet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;[http://127.0.0.1:8899](http://127.0.0.1:8899)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;keypair&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/path/to/your/localnet/keypair.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="c1"&gt;// Devnet&lt;/span&gt;
    &lt;span class="na"&gt;devnet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;[https://api.devnet.solana.com](https://api.devnet.solana.com)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;keypair&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/path/to/your/devnet/keypair.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="c1"&gt;// Mainnet&lt;/span&gt;
    &lt;span class="na"&gt;mainnet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;[https://api.mainnet-beta.solana.com](https://api.mainnet-beta.solana.com)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;keypair&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/path/to/your/mainnet/keypair.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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: (Optional but Recommended) Create Seed Scripts
&lt;/h3&gt;

&lt;p&gt;This is where the magic happens. "Seeding" is the process of initializing your program's state right after deployment.&lt;/p&gt;

&lt;p&gt;Create a &lt;code&gt;seeds/&lt;/code&gt; directory and an &lt;code&gt;index.ts&lt;/code&gt; file inside it (&lt;code&gt;seeds/index.ts&lt;/code&gt;). Here, you'll define a &lt;code&gt;SeedConfig&lt;/code&gt; array.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// seeds/index.ts&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;SeedConfig&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;rocket-anchor&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;seeds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SeedConfig&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&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;program&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;counter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// a name for your program&lt;/span&gt;
    &lt;span class="na"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;function&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;initialize&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;accounts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pda:counter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;authority&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;signer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;systemProgram&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;systemProgram&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;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="c1"&gt;// initial_count&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;seeds&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="na"&gt;function&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;increment&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;accounts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pda:counter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;authority&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;signer&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;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
        &lt;span class="na"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Run 5 times&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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;seeds&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Deploy and Seed!
&lt;/h3&gt;

&lt;p&gt;You're all set. Now, to deploy your program to &lt;code&gt;devnet&lt;/code&gt; and run the seed scripts immediately after, you just run one command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx ra deploy &lt;span class="nt"&gt;--network&lt;/span&gt; devnet &lt;span class="nt"&gt;--seed&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rocket Anchor will handle:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Connecting to the correct network (&lt;code&gt;devnet&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt; Using the correct keypair.&lt;/li&gt;
&lt;li&gt; Deploying your Anchor program.&lt;/li&gt;
&lt;li&gt; Once deployed, it will run the seed scripts you defined for that program.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You're live! No more manual &lt;code&gt;solana program deploy&lt;/code&gt; commands or separate &lt;code&gt;initialize.ts&lt;/code&gt; scripts to run.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Rocket Anchor fills a much-needed gap in the Solana development workflow. By adopting a config-based and scriptable approach to deployments and seeding, it saves time, reduces errors, and lets you focus on what matters: building your program's logic.&lt;/p&gt;

&lt;p&gt;Always remember to test thoroughly on &lt;code&gt;devnet&lt;/code&gt; before deploying to &lt;code&gt;mainnet&lt;/code&gt;. Happy building!&lt;/p&gt;

</description>
      <category>solana</category>
      <category>web3</category>
      <category>smartcontract</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>Introducing Truffle Solidity Data Seeder</title>
      <dc:creator>Zak R.</dc:creator>
      <pubDate>Tue, 27 Apr 2021 02:17:12 +0000</pubDate>
      <link>https://dev.to/zakpie/introducing-truffle-solidity-data-seeder-peg</link>
      <guid>https://dev.to/zakpie/introducing-truffle-solidity-data-seeder-peg</guid>
      <description>&lt;p&gt;The Truffle framework is an awesome toolkit for every solidity and dapp developer, we at &lt;a href="https://libertypie.com"&gt;LibertyPie&lt;/a&gt; make advanced use of the truffle framework.&lt;br&gt;&lt;br&gt;
During &lt;a href="https://github.com/LibertyPie/libertypie-p2p"&gt;LibertyPie's P2P&lt;/a&gt; protocol development, we needed a simple way to seed initial data to different contracts similar to database seeding. &lt;br&gt;&lt;br&gt;
Truffle has great migration support but no seeding of data out of the box.&lt;br&gt;&lt;br&gt;
So we decided to build a simple CLI tool as an npm package for seeding initial data out of the box with 0 configurations.   &lt;br&gt;&lt;/p&gt;

&lt;p&gt;Introducing &lt;a href="https://github.com/LibertyPie/truffle-seeder"&gt;Liberty Pie's Truffle Seeder&lt;/a&gt;, your easy way to seed initial data to any smart contract. Kindly help us improve it by giving us your feedback&lt;/p&gt;

&lt;p&gt;Project: &lt;a href="https://github.com/LibertyPie/truffle-seeder"&gt;https://github.com/LibertyPie/truffle-seeder&lt;/a&gt;&lt;/p&gt;

</description>
      <category>etheruem</category>
      <category>javascript</category>
      <category>blockchain</category>
      <category>truffleframework</category>
    </item>
    <item>
      <title>Introducing LibertyPie’s Wallet Provider</title>
      <dc:creator>Zak R.</dc:creator>
      <pubDate>Thu, 07 Jan 2021 23:58:17 +0000</pubDate>
      <link>https://dev.to/zakpie/introducing-libertypie-s-wallet-provider-17h0</link>
      <guid>https://dev.to/zakpie/introducing-libertypie-s-wallet-provider-17h0</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UAilS8n4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/rvhixu82hskx1uqpuywd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UAilS8n4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/rvhixu82hskx1uqpuywd.png" alt="LibertyPie WalletProvider Image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As the team builds the protocol’s user interface, it is very important to research deeply into which external libraries to include. The user interface must have a rich user experience &amp;amp; also very light weighted.&lt;/p&gt;

&lt;p&gt;Every DApp must find a way to connect to users’ wallet without compromising privacy and security. Fortunately, we found many matured and well-developed libraries such as web3modal (previously web3connect), web3-wallets-kit (by Akropolis), bnc-onboard (by BlockNative) &amp;amp; many more.&lt;/p&gt;

&lt;p&gt;After a careful analysis of these existing solutions, we found reasons which discouraged us from using them. A major reason was the bloat in library size, other reasons included an incomplete library or having to pay for usage in the case of BloackNative bnc-onboard.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--A-ytLQLm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/98fkuqhj29hg3iccwjl8.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A-ytLQLm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/98fkuqhj29hg3iccwjl8.jpeg" alt="WalletProvider Image 2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our final resort was to build a library exactly how we wanted it, thankfully, the initial version of LibertyPie Wallet Provider is successfully published on npm (&lt;a href="https://www.npmjs.com/package/@libertypie/wallet-provider"&gt;https://www.npmjs.com/package/@libertypie/wallet-provider&lt;/a&gt;).&lt;br&gt;
LibertyPie Wallet Provider was built to provide extra advantages over other libraries, a detailed comparison has been given below.&lt;/p&gt;

&lt;h4&gt;
  
  
  Size (according to Bundlephobia.com)
&lt;/h4&gt;

&lt;p&gt;LibertyPie Wallet Provider — 6.9kb minified +gzipped&lt;br&gt;
Web3Modal — 195kb minified + gzipped&lt;br&gt;
bnc-onboard — 65.1kb minified + gzipped&lt;br&gt;
web3-wallets-kit — 784.4kb minified + gzipped&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Best&lt;/em&gt;: LibertyPie Wallet Provider&lt;br&gt;
&lt;em&gt;Worst&lt;/em&gt;: web3-wallets-kit&lt;/p&gt;

&lt;h4&gt;
  
  
  Runtime Dependencies
&lt;/h4&gt;

&lt;p&gt;LibertyPie Wallet Provider— 0&lt;br&gt;
Web3Modal — 6&lt;br&gt;
bnc-onboard — 20&lt;br&gt;
web3-wallets-kit — 9&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Best:&lt;/em&gt; LibertyPie Wallet Provider&lt;br&gt;
&lt;em&gt;Worst:&lt;/em&gt; bnc-onboard&lt;/p&gt;

&lt;h4&gt;
  
  
  Supported Wallets Providers
&lt;/h4&gt;

&lt;p&gt;LibertyPie Wallet Provider — 9&lt;br&gt;
Web3Modal — 11&lt;br&gt;
bnc-onboard — 6&lt;br&gt;
web3-wallets-kit — N/A&lt;/p&gt;

&lt;p&gt;As seen from the data above, LibertyPie Wallet Provider has many merits compared to the other libraries.&lt;br&gt;
NPM: &lt;a href="https://www.npmjs.com/package/@libertypie/wallet-provider"&gt;https://www.npmjs.com/package/@libertypie/wallet-provider&lt;/a&gt;&lt;br&gt;
Github Repo: &lt;a href="https://github.com/LibertyPie/Wallet-Provider"&gt;https://github.com/LibertyPie/Wallet-Provider&lt;/a&gt;&lt;/p&gt;

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