Skip to content

Creating a Web Application

Chris Campbell edited this page Dec 13, 2024 · 12 revisions

This page provides the latest guidance on creating a web application using SDEverywhere.

On this page:

Recommended Tools

If you are new to software development, we highly recommend installing the following (free) tools before developing a project using SDEverywhere:

Recommended Project Structure

It is recommended that you develop your Vensim model and web application code together in the same Git repository. This makes it easy to track history and ensure that changes to your model will work with your application, and vice versa.

If you use the create script as described in the "Quick Start" instructions, it will create directories and files that match the recommended directory structure:

{my-project}/

  config/
    graphs.csv
    inputs.csv
    ...

  model/
    {my-model}.mdl
    checks/
      checks.yaml
    comparisons/
      comparisons.yaml

  packages/
    app/
    core/
    ... (you can add others to better modularize your project, like `graph`, `ui`, `check-bundle`, etc)

  package.json
  sde.config.js
  ... (you can add other config files for e.g., prettier, eslint, GitHub Actions)

The key elements are:

  • config folder: contains the CSV files that you can edit to customize your graphs, sliders, and more
  • model folder: contains your Vensim model along with model check and comparison definitions
  • core library package: wraps the generated JS model and exposes the core configuration for your model
  • app package: contains source code for your web application that you can customize to your liking
  • sde.config.js file: contains the configuration that controls how SDEverywhere converts your Vensim model to JS code and sets up the build plugins

The default project template created by the "Quick Start" instructions contains the source code for a a very simple web application that uses the jQuery framework. We chose jQuery as a sort of "lowest common denominator" framework; the code is easy to read and understand, but there are better, more modern web frameworks that may be suitable for your project.

👉 You are free to choose whatever framework you are most comfortable with, or no framework at all! At Climate Interactive, we use Svelte to develop our En-ROADS and C-ROADS simulators. Other projects have successfully built applications that combine SDEverywhere with other frameworks like React and Vue. No matter which framework you choose, you should be able to build on top of the @sdeverywhere npm packages, which present TypeScript/JavaScript APIs that can be used to build and run your model.

Local Development

When developing a web application, it is important to have a local development environment that allows for rapid iteration.

The default project template created by the "Quick Start" instructions includes a dev script. When you run npm run dev, it uses the sde dev command (from the @sdeverywhere/cli package) to launch a local development environment on your computer. It will start a builder process that rebuilds your app and runs QA checks against your model any time you save changes to your mdl file. You can leave the builder running while developing your model in Vensim. The app and model-check tabs in your browser will refresh automatically whenever you save changes in Vensim or make edits to your application code.

The sde dev process watches the file system and automatically refreshes only those parts of the app or model-check report that are affected by your changes:

  • When you change the mdl file, the builder will regenerate the JavaScript (or C and WebAssembly) version of your model, and the app will refresh automatically.
  • When you change the csv files in the config folder, the builder will generate new JavaScript "spec" files into your packages/core folder.
    • If the config changes affect how the model is generated (for example, if you add a graph with a new variable, or expose a new slider), the builder will regenerate the JavaScript (or C and WebAssembly) version of your model, and the app will refresh automatically.
    • If the config changes only affect how the graphs and sliders appear in your app (for example, if you change a graph title or the units label for a slider), the builder will update those "spec" files and the app will refresh automatically.
  • When you change the checks.yaml or comparisons.yaml files, the live model-check report will re-run the tests and refresh the results automatically.
  • When you change your app source (js or ts) files (under the packages/app/src folder), the app will refresh automatically.
    • We recommend using Vite for both local development and production bundling.
    • The default project template includes a vite.config.js file, and the sde.config.js file includes the @sdeverywhere/plugin-vite package, which allows for seamless integration of Vite into the SDEverywhere build process.
  • When you change your core package source files (under the packages/core/src folder), the app will also refresh automatically.

👉 Note that "refresh automatically" is the key phrase here. Once you launch the local development environment, you can (and should) keep it running alongside Vensim and your other development tools (e.g., Visual Studio Code). The builder will automatically rebuild and regenerate files as described above, so it is not necessary to stop and restart the dev script each time you make a change to your Vensim model or source code. The builder will display build status and error messages, both in your "terminal" window and in a panel in the bottom-right corner of the app and model-check report.

Building and Deploying

When you are ready to share your project with others, SDEverywhere makes it easy to bundle your application so that it can be deployed to any web server.

Similar to what is described in the Local Development section above, the default project template created by the "Quick Start" instructions includes a build script. When you run npm run build, it uses the sde bundle command (from the @sdeverywhere/cli package) to bundle your web application source code and the generated model together into a small set of files that can be deployed to a web server.

The sde bundle process follows a similar set of steps as described above for the sde dev command (the sde.config.js file is used to configure both the sde dev and sde bundle commands). Running npm run build in your project will use Vite under the hood to produce the following:

  • The generated web application (under packages/app/public)
    • index.html
    • index-XXXXXX.css
    • index-YYYYYY.js
  • The generated model-check report (under sde-prep/check-report)
    • index.html
    • index-XXXXXX.css
    • index-YYYYYY.js
  • The generated model-check bundle (under sde-prep)

You can deploy your web application (and/or the model-check report) by uploading the three (html, css, and js) files to any web server capable of serving a static website.

👉 There are many different website hosting services, some of which are completely free. Which one is right for you depends on your project and your goals. Here is a non-exhaustive list of hosting options for you to consider:

  • GitHub Pages is free and easy to configure if your project is already hosted on GitHub
  • GitLab Pages is similarly free and easy to configure if your project is already hosted on GitLab (see this complete example that uses GitLab's CI and Pages features to host an SDEverywhere-generated web app)
  • Amazon S3 offers a generous free tier
  • Vercel, Netlify, and other similar services offer free and paid options
  • Nginx running on your own server or in the cloud (using Amazon EC2 for example)

👉 We highly recommend setting up a continuous integration (CI) system for your project. Using CI, you can have machines automatically build, test, and deploy your project every time you push a change to your Git repository. This makes your build and QA process easier, more reliable, and less dependent on error-prone and manual build/deployment steps. A good default choice is GitHub Actions, especially if your project is already hosted on GitHub (or GitLab CI/CD if your project is hosted on GitLab). You can check out the build.yaml file that we use to configure GitHub Actions for the SDEverywhere project, which runs every time we push a change to the repository.

Testing and Comparing

When developing a model and web application in tandem, it is very helpful to see how model changes affect the behavior of the model as compared to a previous version. The previous version could be the latest version from your primary (e.g., main) branch, or it could be the previous commit on your feature branch, or it could be some known stable/release version.

For any of these cases, you can use the @sdeverywhere/plugin-check package to run checks and comparisons and generate a report that allows you to see at a glance how the model behavior has changed. You can run this "model-check" tool locally in parallel with your app, and you can also run it as part of your continuous integration setup (e.g., on GitHub Actions or GitLab CI/CD) so that the reports can be shared with others.

The sde bundle command (described in Building and Deploying above) will generate a check-bundle.js file. Your generated model and all the related configuration (for displaying graphs, etc) is rolled up into this single file, which can be used as the reference/baseline model for a model-check run.

For more details, consult the Testing and Comparing Your Model page.

Troubleshooting

This section details some error messages that can appear when building a model/application with SDEverywhere.

Error: More than one string with key=graph_001_title (or key=input_001_title)

You might encounter this error when adding new graph or slider rows to the config/graphs.csv or config/inputs.csv files. The values in the id column in those csv files need to be unique, so if you forget to assign a unique identifier for each row, the builder will report this error.

To fix the issue, change the id value for each row to ensure that they are all unique.