Since 2020, Svelte has officially supported TypeScript, however, adding TypeScript to your Svelte project fundamentally changes your toolchain. Although we can’t predict your toolchain’s shape, we can assume it uses a web application bundler like webpack, Parcel, or Rollup. To add TypeScript to a Svelte project, we’ll essentially tell the bundler to transform TypeScript code into JavaScript code.
In this tutorial, we’ll learn how to configure TypeScript for Svelte using the three bundlers mentioned. To follow along with this article, you’ll need:
Let’s get started!
To follow along with the examples in this tutorial, first, we’ll configure our shared build. You should store your source files in the ./src/
directory and your build files in the ./build
directory.
The entry point to the application will be the ./src/index.ts
file, which will import the App
class from the ./App.svelte
file, initialize it, and default export it, as seen in the following example:
import App from './App.svelte'; export default (new App({ target: document.body }));
Svelte will inject the DOM entries into the body of an HTML page. Now, we can implement the App
component:
<script lang="ts"> import { onMount } from 'svelte'; export let result: number = 2 + 2; onMount(() => { setTimeout( () => { result *= 3; }, 500, ); }); </script> <div>{ result }</div>
In the code block below, the <script lang="ts">
tag declaration and the variable definition export let result: number = 2 + 2;
indicate that the code now exists in the TypeScript context.
Next, invoke the build
script in npm by typing yarn build
. The build
script will run the bundler of your choice, compile your project, and produce a single ./build/bundle.js
file. To use the ./build/bundle.js
file, you should create a corresponding ./build/index.html
file:
<!DOCTYPE html> <html lang="en"> <body> <script defer src='./bundle.js'></script> </body> </html>
Now, navigate in your browser to the ./build/index.html
file, and you should see your application in action! Now, let’s take a look at three popular bundlers you can use to migrate your application.
Rollup is a library created by Rich Harris, the creator of Svelte. Therefore, it’s not surprising that Svelte supports Rollup through a custom integration package.
To use Rollup, we’ll first need to install the following packages as development dependencies:
@rollup/plugin-commonjs
@rollup/plugin-node-resolve
@rollup/plugin-typescript
@tsconfig/svelte
rollup
rollup-plugin-svelte
svelte
svelte-preprocess
tslib
typescript
To install these dependencies, we can use the partial ./package.json
file below:
{ "scripts": { "build": "rollup -c" }, "devDependencies": { "@rollup/plugin-commonjs": "20.0.0", "@rollup/plugin-node-resolve": "13.0.4", "@rollup/plugin-typescript": "8.2.5", "@tsconfig/svelte": "2.0.1", "rollup": "2.56.2", "rollup-plugin-svelte": "7.1.0", "svelte": "3.42.1", "svelte-preprocess": "4.7.4", "tslib": "2.3.1", "typescript": "4.3.5" } }
Alternately, we can install these dependencies using Yarn:
yarn add @rollup/plugin-commonjs @rollup/plugin-node-resolve @rollup/plugin-typescript @tsconfig/svelte rollup rollup-plugin-svelte svelte svelte-preprocess tslib typescript -E -D
Next, we’ll configure TypeScript for Svelte and Rollup using the ./tsconfig.json
file below:
{ "extends": "@tsconfig/svelte/tsconfig.json", "include": ["src/**/*"], "exclude": ["node_modules/*"] }
The @tsconfig/svelte
project will import some additional configuration into our project. You can add other settings as desired, but first, ensure they do not conflict with Svelte.
Let’s add the necessary configuration for Rollup. In the code block below, you’ll see our exemplary ./rollup.config.js
file, which sets up the correct preprocessing through the svelte-preprocess
library:
import svelte from 'rollup-plugin-svelte'; import commonjs from '@rollup/plugin-commonjs'; import resolve from '@rollup/plugin-node-resolve'; import sveltePreprocess from 'svelte-preprocess'; import typescript from '@rollup/plugin-typescript'; export default { input: './src/index.ts', output: { format: 'iife', file: './build/bundle.js' }, plugins: [ svelte({ preprocess: sveltePreprocess(), }), resolve({ browser: true }), commonjs(), typescript(), ], };
Next, we’ll create a TypeScript triple-slash directive that informs the compiler about a dependency on the svelte
package. We’ll need to create a file called ./src/global.d.ts
and add the following content:
/// <reference types="svelte" />
With these steps completed, you should be able to compile your project using Rollup.
webpack is another popular bundler that has a customized integration package for Svelte. To migrate TypeScript to Svelte using webpack, we reduced the template-webpack to only the crucial pieces.
To get started, we’ll install the following packages as development dependencies:
@tsconfig/svelte
svelte
svelte-loader
svelte-preprocess
ts-loader
typescript
webpack
webpack-cli
We can install these dependencies using the following package.json
:
{ "scripts": { "build": "webpack" }, "devDependencies": { "@tsconfig/svelte": "1.0.10", "svelte": "3.31.2", "svelte-loader": "3.0.0", "svelte-preprocess": "4.3.0", "ts-loader": "8.0.4", "typescript": "4.0.3", "webpack": "5.16.0", "webpack-cli": "4.4.0" } }
If you prefer to use Yarn, you can run the code below:
yarn add @tsconfig/svelte svelte svelte-loader svelte-preprocess ts-loader typescript webpack webpack-cli -E -D
Now, let’s define a basic TypeScript configuration using the partial ./tsconfig.json
file provided below. As you can see, we’ll import some configuration from the @tsconfig/svelte
project below:
{ "extends": "@tsconfig/svelte/tsconfig.json", "include": ["src/**/*"], "exclude": ["node_modules/*"] }
To configure webpack for Svelte and TypeScript, we’ll have to make the following changes to our webpack configuration:
ts-loader
to process TypeScript filessvelte-loader
and svelte-preprocess
to process Svelte filesThe configuration stored in the ./webpack.config.js
file should look like the following code:
const path = require('path'); const sveltePreprocess = require('svelte-preprocess'); module.exports = { entry: { 'bundle': ['./src/index.ts'] }, resolve: { alias: { svelte: path.dirname(require.resolve('svelte/package.json')) }, extensions: ['.mjs', '.js', '.ts', '.svelte'], mainFields: ['svelte', 'browser', 'module', 'main'] }, output: { path: path.join(__dirname, '/build'), }, module: { rules: [ { test: /\.ts$/, loader: 'ts-loader', exclude: /node_modules/ }, { test: /\.svelte$/, use: { loader: 'svelte-loader', options: { preprocess: sveltePreprocess(), } } } ] }, };
If you performed these steps correctly, you should be able to compile and run your project successfully using webpack.
Finally, we’ll take a look at Parcel. Parcel is not currently supported by Svelte, however, it is a popular and versatile bundler that is used widely by developers.
At the time of writing, Parcel 2 is a release candidate. The information in the section below refers to Parcel 1.
When using Parcel, you need to ensure the following development dependencies are installed:
@tsconfig/svelte
parcel-bundler
parcel-plugin-svelte
svelte
svelte-preprocess
typescript
To perform the migration, you can use the following partial package.json
file:
{ "scripts": { "build": "parcel build ./src/index.html" }, "devDependencies": { "@tsconfig/svelte": "2.0.1", "parcel-bundler": "1.12.5", "parcel-plugin-svelte": "4.0.9", "svelte": "3.42.1", "svelte-preprocess": "4.7.4", "typescript": "4.3.5" } }
To install dependencies using Yarn, copy the code snippet below:
yarn add @tsconfig/svelte parcel-bundler parcel-plugin-svelte svelte svelte-preprocess typescript
For our Svelte files to contain TypeScript code, we’ll need to specify the Svelte configuration in the ./svelte.config.js
file. We’ll use the svelte-preprocess
library.
Here is an exemplary configuration script that is compatible with ECMAScript 5:
const preprocess = require('svelte-preprocess'); module.exports = { preprocess: preprocess(), };
Let’s configure our application for TypeScript using the partial ./tsconfig.json
file below. Your configuration should extend beyond the configuration taken from the @tsconfig/svelte
project:
{ "extends": "@tsconfig/svelte/tsconfig.json", "include": ["src/**/*"], "exclude": ["node_modules/*"] }
Now, feel free to test your setup. With these steps complete, you’ve successfully configured Svelte and TypeScript for Parcel.
As you probably know, bundlers are a rapidly changing technology. Svelte requires a rather extensive integration, so you should always check the behavior of your toolchain when you upgrade dependencies.
Due to the inherent compatibility between Svelte and Rollup, Rollup is a safe choice to use for the durability of your project. Although we can’t say the same for webpack and Parcel, there is always the potential for third-party integration packages to ease the migration from TypeScript to Svelte.
If you use a different bundler, a custom bundler, or no bundler at all, you may need to extensively research the topic on your own and write a custom adapter to allow transpilation in your toolchain. Remember that you need to enable transpilation for both TypeScript and Svelte files.
Although adding TypeScript to a Svelte application may seem self-explanatory due to Svelte’s official support for TypeScript, adding the correct configuration can be quite complex.
In this tutorial, we learned how to configure our TypeScript code for Svelte using Rollup, webpack, and Parcel, three performant bundlers that make it easier to migrate our code.
LogRocket is a frontend application monitoring solution that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.
In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page and mobile apps.
Hey there, want to help make our blog better?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowCompare Prisma and Drizzle ORMs to learn their differences, strengths, and weaknesses for data access and migrations.
It’s easy for devs to default to JavaScript to fix every problem. Let’s use the RoLP to find simpler alternatives with HTML and CSS.
Learn how to manage memory leaks in Rust, avoid unsafe behavior, and use tools like weak references to ensure efficient programs.
Bypass anti-bot measures in Node.js with curl-impersonate. Learn how it mimics browsers to overcome bot detection for web scraping.