Svelte Typescript Use TypeScript with Svelte / Sapper

mhaecker profile image Markus Häcker Updated on ・2 min read

EDIT 2020-07-24: Svelte now officially supports TypeScript

It only takes a few steps to use TypeScript in your .svelte files within <script lang="typescript">...</script> blocks.

The following example shows you how to create a new project based on the default Sapper template and add support for TypeScript. Of course, the steps can also be adopted for projects that are not based on the template or for existing projects.

# Clone the repo and install dependencies, see https://sapper.svelte.dev/docs/#Getting_started
npx degit "sveltejs/sapper-template#rollup" sapper-with-ts-sample
npm i

To do a little testing, add the following to the top of src/routes/index.svelte:

<script lang="typescript">
    export let title: "string = \"Hello TypeScript\";"
    // VS Code will show you an "Unexpected token" error; this is okay at this point


<title>Sapper project template</title>



Then install:

npm i svelte-preprocess typescript --save-dev

Create a new file svelte.config.js in the root folder with the following content:

// See https://github.com/kaisermann/svelte-preprocess#with-svelte-vs-code
const sveltePreprocess = require('svelte-preprocess');

module.exports = {
    preprocess: sveltePreprocess({
        // ...svelte-preprocess options (optional)
    // ...other svelte options (optional)

Also create the TypeScript config file tsconfig.json in the root folder and copy and paste (and adapt it as you need it):

    "include": ["src/**/*"],
    "exclude": ["node_modules/*"],
    "compilerOptions": {
        "target": "es2015",
        "module": "es2015",
        "types": ["svelte"]

Edit rollup.config.js and make 3 insertions:

// ...
import autoPreprocess from "svelte-preprocess"; // add this

export default {
    client: {
        plugins: [
                preprocess: autoPreprocess(), // add this

    // ...

    server: {
        plugins: [
                preprocess: autoPreprocess(), // add this
                // ...
    // ...

Restart VS Code (or which IDE you use). The "Unexpected token" error in your src/routes/index.svelte should have disappeared.


npm run dev

Visit http://localhost:3000 in your browser.
Change the value of your title variable in src/routes/index.svelte to sth. else, save your file and test live reloading in your browser.

Maybe you already got everything you wanted. If you want to replace your client.js/server.js with its TypeScript counterpart, here are the next steps:

Install two more dependencies:

npm i rollup-plugin-typescript2 @types/node --save-dev

Adapt your rollup.config.js (3 inserted lines, 2 edited):

// ...
import typescript from "rollup-plugin-typescript2"; // add

export default {
    client: {
        input: config.client.input().replace(/\.js$/, ".ts"), // edit here
        output: config.client.output(),
        plugins: [
            // ...
            typescript(), // add after commonjs()
    // ...
    server: {
        input: config.server.input().server.replace(/\.js$/, ".ts"), // edit here
        output: config.server.output(),
        plugins: [
            // ...
            typescript(), // add after commonjs()
        // ...

Edit your tsconfig.json:

"types": ["svelte", "node", "@sapper"], // add the last two to the existing types
"typeRoots": ["typings"] // add line

Create a new directory /typings/@sapper in the root folder and in @sapper create a file index.d.ts. Paste:

declare module '@sapper/app';
declare module '@sapper/server';
declare module '@sapper/service-worker';

Finally change the file suffix of the files client.js and server.js in the /src folder from .js to .ts. That's it, happy TypeScripting :)

Posted on by:

mhaecker profile

Markus Häcker


web, bot and voice dev 👨🏼‍💻


Editor guide

Thank you for the tutorial Markus!
I tried to use it, but it gives the error below:

Error: Cannot find module 'C:\sapper-with-ts-sample_sapper_\dev\server\server.js'
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:957:15)
at Function.Module._load (internal/modules/cjs/loader.js:840:27)
at Function.executeUserEntryPoint as runMain
at internal/main/run_main_module.js:18:47 {
requireStack: []

Any ideas?


Make sure you have

input: config.server.input().server.replace(/\.js$/, ".ts"),

and not

input: config.client.input().server.replace(/\.js$/, ".ts"),

for the server
(I had the same error after copy/paste)


You might want to do a

npm install



Is it possible to move the hello variable declaration to another typescript file?

I tried putting this in src/hello.ts:

export let title: string = "Hello, Typescript!"

But importing from index.svelte:

import { title } from "../hello"

Produces an error:

Could not resolve '../hello' from src/routes/index.svelte

But it works fine if I don't use .ts file ...


What you can do if you want to write your TypeScript code to an extra file:

Add this to your index.svelte:

<script src="src/hello.ts">

And in your src/hello.ts:

export let title = "Hello, Typescript!"

Hi Markus,
It did not work for me. I keep getting:

• client
'title' is not defined
39: <svelte:head>
40:   <title>{title}</title>
41: </svelte:head>
• server
'title' is not defined
39: <svelte:head>
40:   <title>{title}</title>
41: </svelte:head>

Do you have a github repo I can clone demonstrating how to use typescript with svelte?


You can create a src/components/hello.ts file

export default "Hello dev";

And import it in src/routes/index.svelte with

    import title from '../components/title.ts';

Or in src/components/hello.ts:

export const title: string = "Hello developer";

with in src/routes/index.svelte:

    import {title} from '../components/title.ts';

The default template repo now provides a script that helps you to convert the project to Typescript.

Just clone the template project

# for Rollup
npx degit "sveltejs/sapper-template#rollup" my-app
# for webpack
npx degit "sveltejs/sapper-template#webpack" my-app

cd my-app

and run node scripts/setupTypeScriptRollup.js


You did had to go and make honor to your namesake* :D

Thanks for this little how-to!

*(Häcker without the umlaut-)