Svelte Kit, the first ‘serverless-first’ framework?
Tags: serverless, svelte, netlify, vercel
Published: 2021-02-03 17:04:50

---
title: Svelte Kit, the first ‘serverless-first’ framework?
published: true
description: Rich Harris, creator of Svelte, claims Svelte is now 'serverless-first'. But is it? And how well does it integrate with serverless platforms like Netlify and Vercel?
tags: serverless, Svelte, Netlify, Vercel
cover_image: https://www.datocms-assets.com/6524/1612365011-svelte-kit-serverless-first-banner.png
canonical_url: https://www.voorhoede.nl/en/blog/svelte-kit-the-first-serverless-first-framework/
---

"The whole serverless thing is a pretty good trend, and **Svelte is now a serverless-first framework**"

[That](https://youtu.be/qSfdtmcZ4d0?t=1194) [quote is from](https://youtu.be/qSfdtmcZ4d0?t=1194) [Rich Harris](https://youtu.be/qSfdtmcZ4d0?t=1194), creator of Svelte. A bold statement, but is the newly introduced Svelte Kit really “serverless-first”? And what does that even mean? And if so, how well can this new Svelte seamlessly integrate with serverless platforms like Netlify and Vercel?

Big fat disclaimer: [Svelte Kit is in early development](https://svelte.dev/blog/whats-the-deal-with-sveltekit). The source code isn't public yet. To get a sneak peek I installed the "next" version (`@1.0.0-next.0`) of Svelte and its [new serverless adapters](https://www.npmjs.com/search?q=%40sveltejs%2Fadapter-):

```bash
npm init svelte@next
npm install -D @sveltejs/adapter-node
npm install -D @sveltejs/adapter-static
npm install -D @sveltejs/adapter-netlify
npm install -D @sveltejs/adapter-vercel
```

My findings are based on sifting through the [compiled code](https://github.com/jbmoelker/test-sveltejs-kit/) with the help of [Sokra's source code visualiser](https://sokra.github.io/source-map-visualization).

## Serverless-first using adapters

Svelte’s answer to become serverless-first in a fragmented landscape of serverless platforms is its introduction of so-called serverless adapters. While all serverless providers like Netlify and Vercel offer similar functionality — static hosting, cloud functions and configurable redirects — they each have their own vendor-specific implementation.
To ensure Svelte runs seamlessly on all of them, Svelte will provide an adapter for each. Each adapter does three things:

- copy Svelte’s compiled client-side JS bundles and other static files to the serverless hosting directory.
- copy Svelte’s server-side JS bundles and a platform specific render function to the serverless functions directory.
- create the redirects configuration with a catch-all route to the serverless render function.

The adapter takes platform specific configuration (files) into account. Here’s the gist taken from the [Svelte adapter for Netlify (`@1.0.0-next.0`)](https://github.com/jbmoelker/test-sveltejs-kit/blob/master/node_modules/%40sveltejs/adapter-netlify/index.js):

```javascript
// get netlify configuration, defined by user in netlify.toml:
const netlify_config = toml.parse(fs.readFileSync('netlify.toml', 'utf-8'));
const publish = path.resolve(netlify_config.build.publish);
const functions = path.resolve(netlify_config.build.functions);

// copy static and client files files to static hosting directory:
builder.copy_static_files(publish);
builder.copy_client_files(publish);

// copy the renderer and server files to cloud functions directory:
fs.copyFileSync(path.resolve(__dirname, 'files/render.js'), `${functions}/render/index.js`);
builder.copy_server_files(`${functions}/render`);

// create _redirects file with catch all route to serverless render function:
fs.writeFileSync(`${publish}/_redirects`, '/* /.netlify/functions/render 200');
```

While I believe adapters are the way forward towards true serverless integration of JavaScript frameworks, I don’t think Svelte is truly serverless-first yet. Here’s why:

## Serverless-first requires server logic

Part of the fun of serverless rendering over static site generation is being able to respond dynamically to incoming requests. For instance if a request has query parameters or a payload, you'd want to use that request data in your Svelte app. As far as I can tell the adapters and Svelte app don't expose this data to the routes yet. Here’s the [serverless `render`function from the Netlify adapter (`@1.0.0-next.0`)](https://github.com/jbmoelker/test-sveltejs-kit/blob/master/node_modules/%40sveltejs/adapter-netlify/files/render.js):

```javascript
exports.handler = async (event) => {
  const { path, httpMethod, headers, queryStringParameters
    // body, // TODO pass this to renderer
    // isBase64Encoded // TODO is this useful?
  } = event;
  const query = new url.URLSearchParams();
  // [...] code to append queryStringParameters to query object

  const rendered = await app.render({
    method: httpMethod, headers, path, query, host: null // TODO
  });

  if (rendered) {
    return {
      isBase64Encoded: false,
      statusCode: rendered.status,
      headers: rendered.headers,
      body: rendered.body
    };
  }
  return { statusCode: 404, body: 'Not found' };
};
```

Judging by the `TODO` comments, this is clearly a work-in-progress. Svelte already passes some request parameters to the Svelte app render function. But as you can see it doesn’t pass the payload `body` and `host` yet. For meaningful serverless apps, Svelte will need to pass these as well as the missing second argument of this lambda handler (`async (event, context)`) and also pass these onto the routes. In addition Svelte will need to normalise the parameters (and context?) best it can between the different serverless providers for a unified developer experience.

Once Svelte exposes the request and context, developers will want to handle these in their app. A good reference of what this could look like is the recently added `[getServerSideProps](https://nextjs.org/docs/basic-features/data-fetching#getserversideprops-server-side-rendering)` [in Next.js](https://nextjs.org/docs/basic-features/data-fetching#getserversideprops-server-side-rendering). Here’s an example of server-side only logic leveraging the request context:

```javascript
// example of server-side only logic in a Next.js route:
const { verify, decode } = require('jws')

export async function getServerSideProps(context) {
  const token = context.req.headers.auth

  if (!token || !verify(token, 'HS256', JWT_SECRET)) {
    return {
      redirect: { statusCode: 401, destination: '/login/' }
    }
  }

  const { userId } = decode(token).payload.app_metadata
  const user = await fetchUser({ userId })

  return {
    // will be passed to the page component as props
    props: { user },
  }
}

export default function Page({ user }) {
  // render page with user data
}
```

Sapper - the Svelte version of Next.js - has [`preload`](https://sapper.svelte.dev/docs#Preloading) which is somewhat similar, but runs both on server- and client-side; and doesn’t expose as much of the context. Whatever it will look like, the new Svelte will need to introduce some way for developers to add their own server-side logic to really be serverless-first.

## Serverless-first in development mode

Serverless providers including Netlify and Vercel worked hard to offer tooling to make local development as close to production as possible. Both `netlify dev` and `vercel dev` offer full support for serverless functions. But while Svelte Kit offers adapters for these serverless providers, they come in the shape of a post-build step:

```bash
npm run build   # svelte-kit build
npm run adapt   # svelte-kit adapt
```

This feels like an afterthought rather than a serverless-first approach. And this means I can’t test my serverless Svelte app in development, but always need to create a (production) build.
Svelte could achieve serverless-first in development mode by creating the redirects configuration during `svelte-kit dev`, connecting the serverless render function to unoptimised server bundles and putting the local server of the selected serverless provider in front of Svelte’s own local server. This way, I can also add my own non-Svelte serverless functions to the project and run them in the same development setup. Svelte already made the client-side development experience instant by adopting Snowpack, now it’s time to do the same for serverless development.

## A serverless-first future

Seeing as Svelte Kit is in early stages and the Svelte team has already proven they can make a serverless framework with Sapper, I’m optimistic the next Svelte will be truly serverless-first. I hope the serverless functions will be extendible and work in development mode in a future version of Svelte.