Transcript
00:00:00BUN's biggest and most controversial update just landed, BUN 1.4, the Rust rewrite.
00:00:04Now, I've made a video on the rewrite drama before, so let's just focus on what's new,
00:00:07because I genuinely like some of it, specifically the standard library stuff,
00:00:11because it's now a built-in headless browser, image library, pseudo-terminal, markdown,
00:00:15cronjobs, tables, and more, replacing 15 dependencies you might be using.
00:00:19Over the last few years, one of the biggest JavaScript complaints has been lack of a standard
00:00:23library, and BUN is fixing that, which is a pretty nice move in a world of weekly supply chain attacks.
00:00:30First up, we can uninstall Playwright and Puppeteer, and use BUN WebView instead.
00:00:37With this code here, I can control a headless browser, find the subscribe button, and click it,
00:00:41although I can't run this on your machine yet, so you're going to have to click subscribe for me.
00:00:44All of the input methods like click, type, press, and scroll, dispatch native browser events,
00:00:48so the page should think you're a real user. On Mac, this uses the system's webkit,
00:00:52so Safari's engine, meaning there's nothing to install, but if you want a Chrome instance,
00:00:56you can set the backend option to Chrome, and this will use an installed Chrome or Chromium instance,
00:01:01which is what you'd do if you're using Windows or Linux. This can actually run a headless Chrome
00:01:04subprocess, or it can connect to an already running Chrome instance, so using this code here,
00:01:09I can drive the open version of Chrome on my Mac, all from BUN. On top of this,
00:01:13you can also use Evaluate to run JavaScript on the page, and get the results back in native
00:01:17JavaScript values, and if there's no API for a feature that you want yet, you can drop down to
00:01:21the raw CDP commands. I can see this being pretty good for some lightweight browser automations,
00:01:25I don't think it fully replaces Playwright yet, it's not got a test runner or trace viewer,
00:01:29but for things like scraping or computer use scripts, it's not a bad option.
00:01:32Next up, let's uninstall Sharp and use BUN.image instead. This is a full image library,
00:01:37letting us take a file, call.image on it, then chain operations like resizing it, rotating,
00:01:42flipping it, flopping it, changing the brightness, the sharpness, and converting it into a bunch of
00:01:46different image formats. It will also let you read metadata, like width, height, and format,
00:01:50without decoding the pixel data. Another cool option that I really like is the ability to create
00:01:54a placeholder image. This is a low quality version that you can inline in HTML before the real image
00:01:59loads. BUN.image is one of the features that I'm most excited about using because I've actually had
00:02:04issues with deployments and builds before that have been related to Sharp. Now if I use BUN,
00:02:08I don't have to think about it. I also don't have to think about Marked anymore because we can now
00:02:12just use BUN.markdown for parsing Markdown instead. This is just three APIs.
00:02:16BUN.markdown.html renders Markdown to a HTML string. BUN.markdown.render renders Markdown with
00:02:22custom callbacks for each element. This gives you the flexibility to render HTML with custom classes,
00:02:27ANSI terminal output, or any other string format. BUN.markdown.react renders Markdown to React.jsx,
00:02:33and this also lets you pass in any component you want for each element, so you can get some really
00:02:37nicely styled Markdown. There's also a bunch of options that you can toggle to control the Markdown
00:02:41features that you want. You can have things like GitHub formatted tables, auto links,
00:02:45heading IDs, and wiki links, although one warning they point out is that HTML output is not sanitized,
00:02:50so raw HTML, event header attributes, JavaScript, they all pass straight through, so if you're
00:02:54rendering Markdown that users wrote, that is still your problem to solve. Regardless, there is so much
00:02:59Markdown being generated these days that this seems like a pretty good addition to me. Moving on, you
00:03:03can now uninstall Node.pty. BUN.terminal gives you a built-in pseudo terminal, letting you drive
00:03:08Bash, Vim, or HTOP from JavaScript. If you've ever tried to ship a terminal inside of an Electron app,
00:03:12you know the pain. This is actually an addition to BUN.spawn. You pass it the terminal option and it
00:03:17spawns a subprocess with a pseudo terminal attached. The subprocess sees a real terminal, which enables
00:03:22colored output, cursor movement, and interactive prompts, and once you have a terminal, you can
00:03:26write data to that terminal, resize the terminal, close the terminal, and lots more. You can also
00:03:31create your own terminal, which lets you reuse it across subprocesses. I'm starting to see a pattern
00:03:35in all of these features. They seem to be something that Claude Code would use, so I wish they'd
00:03:39open-source that so we could see these features being used at scale. The next dependency we're
00:03:43uninstalling is Node.chron, because we can now just use BUN.chron. If you pass this a function,
00:03:47it will simply run on the event loop with no system chron involved, but if you pass this a script,
00:03:51it will register an OS-level chron job that actually uses chron tab on Linux, launch to your macOS,
00:03:56and the task scheduler on Windows. You can use standard chron syntax, including name days and helpers like
00:04:01daily, and it also supports parsing that chron syntax as well, which will return the next matching date
00:04:05in the system's local time zone. And talking of time zones, all jobs run in the local time by default,
00:04:11but it does have explicit options to change this, so you can be sure of when this is going to run.
00:04:15Next up in my schedule is to tell you to uninstall concurrently or npm run all, because BUN now has
00:04:20its own parallel option. Using this flag lets you run multiple package.json scripts concurrently,
00:04:24and the output is nicely prefixed with the script name that it's from. It also lets you use a glob
00:04:28match for the script names, it has a filter for what packages to run the command in within your
00:04:32workspace, and it also has an option to let the other scripts keep going if one of them errors out. It also
00:04:37doesn't just have to be concurrent either, you can also use sequential to run scripts one at a time
00:04:41with the same prefixed output and filtering. This is probably the feature that I see myself using the
00:04:45most. Our next uninstall is any tar archive library. BUN.archive is a fast native implementation
00:04:50of tar and gzip. Making one is just an object where the keys are the paths and the values are the
00:04:55contents, and the contents can be anything from a string, blob, UIN8 array, or an array buffer. For compression,
00:05:00you can also use the compress option, set to gzip, and a level from 1 to 12. Obviously you can then
00:05:05extract these with options like a glob pattern to only extract specific files, and a feature I really
00:05:10like is you can read an archive without extracting it. This code here can pull lodash from the npm
00:05:14registry and read its package.json without a single file being extracted. So far we've removed the need
00:05:19for about 7 npm packages, and there's still more to go, although these ones are smaller features so we
00:05:24can get through them quicker. First, BUN.serve can now serve static files, replacing the need for
00:05:28serve static, and this is great for that public folder of your website. Second, BUN added support
00:05:33for JSON5 and XML, so you don't need their packages anymore. You can import, parse, and stringify both
00:05:38of the formats in BUN. The last three are helpers for the terminal. We have BUN.sliceansy, BUN.wrapansy,
00:05:43and BUN.stringwidth, which gives you terminal column aware slicing, wrapping, and measurement,
00:05:47replacing the need for packages like sliceansy, CLI truncate, wrapansy, and stringwidth.
00:05:52Overall, that's about 15 packages gone, and I've only covered about half of this release.
00:05:56The TLDR of most of this blog post is a lot of things got faster, CPU usage improved, startup got
00:06:01faster, and despite all of these features, the binary got 17% smaller. Oh, and it's written in Rust.
00:06:06One bonus feature worth mentioning is that BUN.install got a global virtual store.
00:06:10If you enable isolated linker, packages get extracted once on your machine and simlinked
00:06:14to your node modules, rather than being copied into every single project separately. This should
00:06:19make it faster and also save space if you have loads of projects. So what do you think about BUN now?
00:06:23Do you use it? Will you use any of these features? Let me know in the comments down below,
00:06:27wait there, subscribe, and as always, see you in the next one.
00:06:36I'll see you next time.
Community Posts
No posts yet. Be the first to write about this video!
Write about this video