Skip to main content



In this tutorial, we will walk through how to convert the TypeScript-React TodoMVC application into a Klotho-annotated application.

TodoMVC is an open-source project, offering an application implemented using MV* concepts in most of the popular JavaScript MV frameworks of today.


Developers are able to choose from many MV frameworks today. These frameworks do the heavy lifting for the development of content, but do not contribute to the effort required to host the application. By using klotho, developers can use the MV framework they prefer and have a consistent experience in their cloud development process.

Getting started with TodoMVC and Klotho



Clone the TodoMVC git repo and navigate to the typescript-react example.

git clone
cd todomvc/examples/typescript-react

Run the application locally

To run the initial application locally, we will follow the instructions below, presented from the GitHub page's readme

A standalone TypeScript compiler is available on NPM.

npm install typescript

To compile the TypeScript in this project:

# from examples/typescript-react
$ ./node_modules/typescript/bin/tsc -p ./js/

To be able to run the output JS files in the browser:

# from examples/typescript-react
$ ./node_modules/browserify/bin/cmd ./js/app.js -o ./js/bundle.js"

To run the app, spin up an HTTP server (e.g. python -m SimpleHTTPServer) and visit http://localhost/.../myexample/. Alternatively you can run:

from examples/typescript-react

$ npm run start

Klotho-ify the application

The initial serve.js file is responsible for hosting our local server and vending our assets. To make our TodoMVC application cloud native, we will modify this file to be Klotho-annotated.

Update serve.js to contain the following contents:

* @klotho::static_unit {
* id = "static-unit"
* index_document = "index.html"
* static_files = ["js/*", "serve.js"]
* }

var static = require('node-static');
var file = new static.Server('./');

require('http').createServer(function (request, response) {
request.addListener('end', function () {
file.serve(request, response);

console.log('Serving on http://localhost:4200/');

We specify the following annotations:

  • @klotho::static_unit: Lets Klotho know to staticly host the files as a website.

Compiling the application

We will install our applications dependencies from our package.json in our root directory by running:

npm install

We will compile our react application files in our ./js directory by running:

npx tsc -p js

We will use Browserify to make our application code compatible with browsers. Browserify will bundle code from the passed in arguement and output it into our ./js/bundle.js file by running:

 ./node_modules/browserify/bin/cmd.js ./js/app.js -o ./js/bundle.js

Our compiled files are ready to be run through Klotho.

klotho . --app sample --provider aws
██╗  ██╗██╗      ██████╗ ████████╗██╗  ██╗ ██████╗
██║ ██╔╝██║ ██╔═══██╗╚══██╔══╝██║ ██║██╔═══██╗
█████╔╝ ██║ ██║ ██║ ██║ ███████║██║ ██║
██╔═██╗ ██║ ██║ ██║ ██║ ██╔══██║██║ ██║
██║ ██╗███████╗╚██████╔╝ ██║ ██║ ██║╚██████╔╝
╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝

Adding resource static_unit:static-unit
Adding resource topology:sample
Adding resource aws_template_data:sample
Adding resource infra_as_code:Pulumi (AWS)

In the ./compiled directory, you'll find the Infrastructure-as-Code for your cloud-native application ready for deployment.

Deploying the application

To deploy the application, refer to the deploying guide.

At this point, we can reach the CloudFront domain, shown in our Pulumi output, which hosts our website.

Access our cloud application

To access our deployed application, just enter the CloudFront domain name from our steps above into your browser. Cloud website

Re-run the application locally

Now that our klotho compile steps will generate our new ./js/bundle.js file, there are no extra steps we need to take to run our application locally.

# from examples/typescript-react/
$ npm run start

local website