Nov 24, 2023Sönke Hahn

garn version v0.0.16

Release announcement for garn version v0.0.16

Release: Garn version v0.0.16share

A few days ago we released version v0.0.16 of Garn and the accompanying typescript library.

How to get itshare

If you don't have Garn installed yet you can follow our installation instructions. If you already have Garn installed, then follow our updating guide.

New features: tl;dr versionshare

We added a plugin system to Garn. It allows to bundle up common functionality into so-called Plugins, publish them in the Garn typescript library (or in third-party libraries) and re-use them in various Garn projects.

We also built two plugins that can be used independently, but that are also designed to work well together:

If you have a vite project, you can try it out like this:

  • Run garn init in your vite project,
  • modify the created garn.ts file to add the deployToGhPages plugin to your project,
  • modify your vite.config.js file to set base to "/$YOUR_GITHUB_REPO/",
  • run garn run $YOUR_PROJECT.deployToGhPages and
  • run git push origin gh-pages:gh-pages.

New features: The longer versionshare

Pluginsshare

We've created a new plugin system, based on the Plugin type. Plugins can be used to add some functionality to a project (such as tests, or formatters, or linters). We have some Plugins in the pipeline (for prettier, eslint, etc.). But it's also relatively easy to create your own plugins! We'll soon write a blog post to help you get started with that, and to explain plugins in more detail. But for this release, we're most excited about two of the first plugins that we created: vite and deployToGhPages.

The vite Pluginshare

Suppose you have a vite project that you're configuring with Garn. In your garn.ts file you can add the vite plugin for example like this:

import * as garn from "https://garn.io/ts/v0.0.16/mod.ts";

export const frontend = garn.javascript
  .mkNpmProject({
    description: "my project",
    src: ".",
    nodeVersion: "18",
  })
  .add(garn.javascript.vite);

Adding the vite plugin will allow you to do three new things:

  • Run garn run frontend.dev to spin up the development version of your web app,
  • run garn run frontend.preview to spin up a preview of your production build locally and
  • run garn build frontend.build to bundle your web app.

(This last command builds your web app bundle in a deterministic build environment, so you can be sure that — given the same repo state — you'll always get the same result.)

To get started quickly on existing vite projects, you can run garn init on them to create a garn.ts file that includes the vite plugin.

This makes it easy to work on your vite projects and create deterministic web app bundles from them. You can serve the created bundles on a web server in any way you like. One very easy way to deploy a frontend is to use Garn's deployToGhPages plugin.

The deployToGhPages Pluginshare

The deployToGhPages plugin allows you to easily deploy web apps to GitHub pages. To deploy the example vite project from the previous section you need to:

  1. Call .add(garn.deployToGhPages((self) => self.build)) on the project in the garn.ts file. This tells garn to use the plugin and passes in the build package (which is the web app bundle) to be deployed.

  2. Set the base setting in your vite.config.js file to "/$YOUR_GITHUB_REPO/". vite projects need to know the base url they'll be running under and this setting takes care of that. It's documented here.

  3. Run garn run frontend.deployToGhPages. This will create a gh-pages branch (if that doesn't exist yet) and add a new commit to that branch that includes all the files from your web app bundle.

  4. Push the new commit to the gh-pages branch with e.g. git push origin gh-pages.

  5. Wait for GitHub to deploy your changes to https://$YOUR_GITHUB_USER.github.io/$YOUR_GITHUB_REPO/.

The vite and the deployToGhPages plugins are designed to work well together, but they're also designed to be flexible and composable. So of course you can build your vite project and deploy it to a website in another way. And you can also create your own Package manually and then use the deployToGhPages plugin to have GitHub serve those built files. Here's a simple example for that:

import * as garn from "https://garn.io/ts/v0.0.16/mod.ts";

export const example = garn
  .mkProject(
    {
      description: "foo",
      defaultEnvironment: garn.emptyEnvironment,
    },
    {},
  )
  .addPackage("mySimplePackage", "echo 'hello world' > $out/index.html")
  .add(garn.deployToGhPages((self) => self.mySimplePackage));

Running garn run example.deployToGhPages && git push origin gh-pages:gh-pages will mean that 'hello world' will be served as the response body from https://$YOUR_GITHUB_USER.github.io/$YOUR_GITHUB_REPO/.

Here's an example of a vite project (created from this template repo) where we added a garn.ts file to show how it all works: https://github.com/garnix-io/garn-example-vite-reactts-eslint-prettier. To see it in action for yourself you can fork that repo, clone it locally and run:

garn run webApp.deployToGhPages

Other Changesshare

Some other changes also made it into the v0.0.16 release:

  • Allow building packages that are nested within projects with garn build projectName.packageName.
  • Allow building top-level packages with garn build packageName.
  • Allow adding packages to projects with .addPackage("packageName", "{build script writing to $out}").
  • Expose some useful nested nix packages in the garn nixpkgs.ts module.

Continue Reading

Nov 16, 2024Julian K. Arni

We've added incremental compilation to garnix. In this blog, we discuss prior art on incremental compilation in Nix, and describe our own design.

Nov 11, 2024Julian K. Arni

How we designed our private caches.

Aug 27, 2024Julian K. Arni

A short note about custom typing for functions in Nix

View Archive
black globe

Say hi, ask questions, give feedback