{"id":13455802,"url":"https://github.com/concrete-utopia/utopia","last_synced_at":"2025-04-23T21:00:11.768Z","repository":{"id":37043150,"uuid":"267429516","full_name":"concrete-utopia/utopia","owner":"concrete-utopia","description":"Design ❤️ Code","archived":false,"fork":false,"pushed_at":"2025-04-10T08:04:15.000Z","size":211289,"stargazers_count":3756,"open_issues_count":331,"forks_count":173,"subscribers_count":28,"default_branch":"master","last_synced_at":"2025-04-23T20:59:18.720Z","etag":null,"topics":["future","now","utopia"],"latest_commit_sha":null,"homepage":"https://utopia.app","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/concrete-utopia.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":"contributing.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-05-27T21:25:28.000Z","updated_at":"2025-04-19T16:02:46.000Z","dependencies_parsed_at":"2023-11-07T01:55:19.236Z","dependency_job_id":"d3ea1f5c-ae02-4847-a0b6-dfc5a8ac84a9","html_url":"https://github.com/concrete-utopia/utopia","commit_stats":{"total_commits":2447,"total_committers":19,"mean_commits":"128.78947368421052","dds":0.8034327748263179,"last_synced_commit":"b00117d11559bac9fc4c4301bac95b63700257fc"},"previous_names":[],"tags_count":876,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/concrete-utopia%2Futopia","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/concrete-utopia%2Futopia/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/concrete-utopia%2Futopia/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/concrete-utopia%2Futopia/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/concrete-utopia","download_url":"https://codeload.github.com/concrete-utopia/utopia/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250514767,"owners_count":21443208,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["future","now","utopia"],"created_at":"2024-07-31T08:01:11.381Z","updated_at":"2025-04-23T21:00:11.726Z","avatar_url":"https://github.com/concrete-utopia.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"![](https://github.com/concrete-utopia/utopia/workflows/Build%20And%20Release%20On%20Push%20To%20Master/badge.svg) [![RelativeCI](https://badges.relative-ci.com/badges/CdA4FG8pCI7TO2sSFLyN?branch=master)](https://app.relative-ci.com/projects/CdA4FG8pCI7TO2sSFLyN) \u003c!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section --\u003e\n[![All Contributors](https://img.shields.io/badge/all_contributors-13-orange.svg?style=flat-square)](#contributors)\n\n\u003c!-- ALL-CONTRIBUTORS-BADGE:END --\u003e\n\n# Welcome to Utopia 🏝\n\nUtopia is an integrated design and development environment for React. It uses React code as the source of truth, and lets you make real time changes to components by editing it and using a suite of design tools. It's early software, but you can [try it today](https://utopia.app/project), look at an [example project](https://utopia.app/p/36ae27be-welcome-to-utopia/), or read about it on our [blog](https://utopia.app/blog)!\n\n[Try Utopia Now!](https://utopia.app/project)\n\n![screenshot of utopia](https://user-images.githubusercontent.com/2226774/93580752-7b7b8e80-f9a0-11ea-8663-39683a53df2e.png)\n\n[Start the editor](https://utopia.app/project)\n\n# For contributors only: Installing Utopia on your machine\n\nPlease note: to use Utopia, visit [utopia.app](https://utopia.app/). Installing it locally is for feature development of Utopia itself: it's slower - sometimes very significantly so. It still needs connection to our servers. And you won't be able to edit projects in the file system on your machine if you install it locally.\n\nTo contribute to Utopia, you'll need to clone the repo, install the prerequisites, and then run the editor for the first time.\n\n## Quick Start for contemporary MacOS\n1. Clone the repo\n2. Install Nix-Shell [nix-shell](https://nixos.org/download.html) `sh \u003c(curl -L https://nixos.org/nix/install)`\n3. Close terminal, start new terminal session, navigate to repo folder, run `nix-shell`. first run will take a while it will look like nothing will happen.\n4. Generate and copy a Github Token [here](https://github.com/settings/tokens) (fine-grained or classic, longest expiration. No need to tick any of the permission checkboxes for classic)\n5. First run and build: open terminal `GITHUB_TOKEN=\u003ctoken from above\u003e start-full`.\n6. Wait - this step will take a while and start with (harmless) errors. Once you see the scratchpad, check the server tab - it'll take the longest (many minutes).\n7. Load the editor at `http://localhost:8000/p`. \n8. Subsequent runs: `start-minimal` (this won't rebuild everything) except for server and infra-level changes\n9. Editor hot-reloads and rebuilds as needed; refresh browser for asset changes\n10. `stop-dev` in the Scratchpad stops the server.\n11. Install [direnv](https://github.com/concrete-utopia/utopia#using-direnv-to-make-your-life-easier) to start nix-shell automatically `brew install direnv`\n\n## Install the Prerequisites\n\n- [nix-shell](https://nixos.org/download.html). If you are on macOS Catalina or later, you will be prompted to include an extra flag in the install script. If using Windows follow [this guide](https://nathan.gs/2019/04/12/nix-on-windows/). If you don't want to use nix, we have instructions [here](https://github.com/concrete-utopia/utopia#running-this-without-nix)\n- [direnv](https://github.com/concrete-utopia/utopia#using-direnv-to-make-your-life-easier). If you don't have `direnv` installed, you'll need to run `nix-shell` before any of the `start` commands, and switching to nix will be a bit slower.\n\nNB: If you're on Windows, you'll first need to set up the [Windows Subsystem for Linux (wsl)](https://docs.microsoft.com/en-us/windows/wsl/install-win10).\n\n## You need to generate a `GITHUB_TOKEN`\n\nA Github token is required to build VS Code, as there are some dependencies downloaded via the Github API which will be rate limited without one, causing the build to sporadically fail with a 403 error. To prevent that, generate a new Github token [here](https://github.com/settings/tokens) (if you have access to fine-grained tokens, use one of those, but if not then a \"classic\" token will be fine).\n\nGive it the longest expiration time possible, readonly public access, and don't give it any permissions for anything else. Then copy that token somewhere so that you can use it in the next step.\n\n## Run the Editor for the first time\n\nThe first time running the editor, run the following script:\n\n```\nGITHUB_TOKEN=\u003ctoken from above\u003e start-full\n```\n\n(You'll only need to do this once, and it will take quite some time to download and build various dependencies. After that, you can usually use `start-minimal`.)\n\n## Working in the dev environment\n\nBoth of these scripts result in a tmux session with all of the various servers running and watching for changes. You can see all of the active sessions in the bar along the bottom, prefixed by the \"window\" number that they are running in. You should be able to click on each of those to switch to viewing that session, or if that doesn't work you can use the key combo `cmd`+`b` (macOS) or `ctrl`+`b` (Linux or Windows), followed by the number for that session. (see [here](https://github.com/tmux/tmux/wiki/Getting-Started#changing-the-current-window) for the relevant tmux docs)\n\nTo shut them down, in the \"Scratchpad\" tab of the session run the following command:\n\n```\nstop-dev\n```\n\n### Finally, loading the running application\n\nNow the editor should load on [http://localhost:8000/p](http://localhost:8000/p), or [http://localhost:8000](http://localhost:8000/) when developing the website itself.\n\n## Pull request bundle support.\n\nWhen a series of environment variables are set (see `Branches.hs`), the editor supports the ability to get a bundle of editor code from S3 that was created from a PR, and load that instead of the code currently held locally. Which means that changes can be tested without spinning up multiple environments.\n\nTo use this if the URL currently is `https://utopia.pizza/p/e976df60-phase-rutabaga/`, the branch name would be added on in a query parameter like so: `https://utopia.pizza/p/e976df60-phase-rutabaga/?branch_name=my-test-branch`.\n\nLimitations:\n\n- Doesn't currently support Monaco because of the way that builds the workers in a special webpack plugin, so changes to the version of Monaco in that branch may fail in unusual ways.\n- Anything that isn't editor code will not be changed by this, such as the website code or the server endpoints.\n\n# Troubleshooting\n\n## I'm on macOS and Nix has suddenly stopped working\n\nPart of the nix installation will add a hook into `/etc/bashrc`, which can be wiped by a macOS update. There is an open bug ticket for that [here](https://github.com/NixOS/nix/issues/3616). If this has happened to you, you'll need to manually add that hook back in, or alternatively add it to your own `~/.zshrc` (where it won't be overwritten), copying and pasting the hook exactly as follows:\n\n```\n# Nix\nif [ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ]; then\n  . '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh'\nfi\n# End Nix\n```\n\n## fsevents\n\nIf you notice that 1 or more CPU cores are running 100% because of `node` processes, it is probably webpack-dev-server having trouble with `fsevents` on MacOS. To fix it, run `pnpm install fsevents` in the `utopia/editor` directory. see https://github.com/webpack/webpack/issues/701#issuecomment-216082726\n\n## Installation error on `utopia-vscode-extensions` step\n\nIf you see an error to the effect of\n\n```\nUsage Error: The nearest package directory (/path/to/utopia/utopia-vscode-extension) doesn't seem to be part of the project declared in /path/to/utopia.\n\n- If /path/to/utopia isn't intended to be a project, remove any yarn.lock and/or package.json file there.\n- If /path/to/utopia is intended to be a project, it might be that you forgot to list utopia-vscode-extension in its workspace configuration.\n- Finally, if /path/to/utopia is fine and you intend utopia-vscode-extension to be treated as a completely separate project (not even a workspace), create an empty yarn.lock file in it.\n```\n\nIt could be caused by a `.yarnrc` or `.yarnrc.yml` file located in a parent directory. `.yarnrc` files are [used to configure yarn setting](https://yarnpkg.com/configuration/yarnrc) and will effect projects in all child directories below them. This can change the yarn version of utopia to one that will produce the above error. Simply removing the `.yarnrc` or `.yarnrc.yml` file will fix this error.\n\n## Running this without Nix\n\nWe highly recommend using Nix to make life easier, but if you're having trouble with that or would prefer not to, then there is always the option to run each of the various scripts individually.\n\n**You'll first need to build VS Code and install a few dependencies:**\n\n```\ncd [root-directory]/utopia-vscode-extension\npnpm install\npnpm run build\n\ncd [root-directory]/vscode-build\nyarn\nyarn run build\n\ncd [root-directory]/editor\npnpm install\n```\n\n**Then, to run the application, you'll need multiple things running concurrently...**\nThe server:\n\n```\ncd [root-directory]/server\nhpack\ncabal new-run -j --disable-optimization --disable-profiling --disable-documentation --disable-library-coverage --disable-benchmarks utopia-web -- +RTS -N -c\"\n```\n\nPostgreSQL:\n\n```\ncd [root-directory]\nPGLOCK_DIR=\"`pwd`/.pglock/\"\nmkdir -p $PGLOCK_DIR\npg_ctl -D utopia-db stop\ninitdb -D utopia-db\npg_ctl -D utopia-db -l pglog.txt -o \"--unix_socket_directories='$PGLOCK_DIR' -c log_statement=none\" start\npsql -o /dev/null -h \"$PGLOCK_DIR\" -d utopia -tc \"SELECT 1 FROM pg_database WHERE datname = 'utopia'\" || create-db\ntail -f pglog.txt\n```\n\n`tsc` to compile the editor:\n\n```\ncd [root-directory]/editor\npnpm tsc --watch \u0026\u0026 NODE_OPTIONS=--max_old_space_size=4096\n```\n\nVite to run the editor:\n\n```\ncd [root-directory]/editor\npnpm run dev-fast\n```\n\nThe utopia-vscode-common module:\n\n```\ncd [root-directory]/utopia-vscode-common\npnpm install\npnpm run watch-dev\n```\n\nThe utopia-vscode-extension module:\n\n```\ncd [root-directory]/utopia-vscode-extension\npnpm install\npnpm run watch-dev\n```\n\nA script for pulling changes to the above extension into VS Code:\n\n```\ncd [root-directory]/vscode-build\nyarn run pull-utopia-extension\n```\n\nThe website project (if developing that)\n\n```\ncd [root-directory]/website-next\npnpm install\nBROWSER=none pnpm run dev\n```\n\n## Using direnv to make your life easier\n\nSince a lot of this requires using `nix-shell` everywhere, you can just use [direnv](https://direnv.net/) to make that a lot simpler. Not only will this automatically use a nix shell whenever you `cd` into the project folder, but it also adds caching to vastly speed up the opening of that shell. You can install direnv by using [brew](https://brew.sh/):\n\n```\nbrew install direnv\n```\n\nTo actually run direnv you need to hook it into your shell by following the instructions [here](https://direnv.net/docs/hook.html).\n\nThen to configure it, in your \\$HOME directory add a file `.direnvrc` with the following contents (copied from https://github.com/direnv/direnv/wiki/Nix#using-a-global-use_nix-with-garbage-collection-prevention):\n\n```\nuse_nix() {\n  local path=\"$(nix-instantiate --find-file nixpkgs)\"\n\n  if [ -f \"${path}/.version-suffix\" ]; then\n    local version=\"$(\u003c $path/.version-suffix)\"\n  elif [ -f \"${path}/.git\" ]; then\n    local version=\"$(\u003c $(\u003c ${path}/.git/HEAD))\"\n  fi\n\n  local cache=\".direnv/cache-${version:-unknown}\"\n\n  local update_drv=0\n  if [[ ! -e \"$cache\" ]] || \\\n    [[ \"$HOME/.direnvrc\" -nt \"$cache\" ]] || \\\n    [[ .envrc -nt \"$cache\" ]] || \\\n    [[ default.nix -nt \"$cache\" ]] || \\\n    [[ shell.nix -nt \"$cache\" ]];\n  then\n    [ -d .direnv ] || mkdir .direnv\n    nix-shell --show-trace --pure \"$@\" --run \"\\\"$direnv\\\" dump bash\" \u003e \"$cache\"\n    update_drv=1\n  else\n    log_status using cached derivation\n  fi\n  local term_backup=$TERM path_backup=$PATH\n  if [ -n ${TMPDIR+x} ]; then\n    local tmp_backup=$TMPDIR\n  fi\n\n  eval \"$(\u003c $cache)\"\n  export PATH=$PATH:$path_backup TERM=$term_backup TMPDIR=$tmp_backup\n  if [ -n ${tmp_backup+x} ]; then\n    export TMPDIR=${tmp_backup}\n  else\n    unset TMPDIR\n  fi\n\n  # `nix-shell --pure` sets invalid ssl certificate paths\n  if [ \"${SSL_CERT_FILE:-}\" = /no-cert-file.crt ]; then\n    unset SSL_CERT_FILE\n  fi\n  if [ \"${NIX_SSL_CERT_FILE:-}\" = /no-cert-file.crt ]; then\n    unset NIX_SSL_CERT_FILE\n  fi\n\n  # This part is based on https://discourse.nixos.org/t/what-is-the-best-dev-workflow-around-nix-shell/418/4\n  if [ \"$out\" ] \u0026\u0026 (( $update_drv )); then\n    local drv_link=\".direnv/drv\"\n    local drv=\"$(nix --experimental-features nix-command show-derivation $out | grep -E -o -m1 '/nix/store/.*.drv')\"\n    local stripped_pwd=${PWD/\\//}\n    local escaped_pwd=${stripped_pwd//-/--}\n    local escaped_pwd=${escaped_pwd//\\//-}\n    ln -fs \"$drv\" \"$drv_link\"\n    ln -fs \"$PWD/$drv_link\" \"/nix/var/nix/gcroots/per-user/$LOGNAME/$escaped_pwd\"\n    log_status renewed cache and derivation link\n  fi\n\n  if [[ $# = 0 ]]; then\n    watch_file default.nix\n    watch_file shell.nix\n  fi\n}\n```\n\nAnd add a `.envrc` file to the root folder of the project with the following contents:\n\n```\nuse nix\n```\n\n(This file is deliberately contained in the `.gitignore` because it is supposed to be personal to you - it allows you to add custom environment variables that will always be in scope whenever you're in this directory)\n\nPlease update your .zshrc (or .bashrc) to [hook it into the shell](https://direnv.net/docs/hook.html), for example for zsh add this line:\n\n```\neval \"$(direnv hook zsh)\"\n```\n\nAfter this step open a new shell window and enter the utopia directory. Direnv should be activated as soon as you enter, you can use the `start` and `start-performance` scripts without manually running nix-shell.\n\n## Unit Tests with Jest\n\nUse the following nix scripts:\n\n```\ntest-editor\n```\n\nContinuous mode:\n\n```\ntest-editor-watch\n```\n\nOn macOS, when trying to watch, you might run into an error message about number of open files. In that case, install watchman:\n\n```\nbrew install watchman\n```\n\n## Browser tests with Karma\n\n_Tip: If you want to focus on a specific test suite you can change `describe(...` to `describe.only(...` and if you want to run a specific test case, you can do the same with `it.only(...` ._\n\nUse the following nix scripts:\n\nOne-off run with a headless Chrome (same as on the CI):\n\n```\ntest-editor-browser\n```\n\nDebugging (bring your own Chrome):\n\n```\ntest-editor-browser-debug\n```\n\nIn debugging mode, Karma will be run in watch mode, and will not use a managed browser. Once the Karma webpack server is ready, it will print something like this to the terminal:\n\n```\n01 03 2022 11:20:17.412:WARN [karma]: No captured browser, open http://localhost:9876/\n```\n\nUse your own Chrome browser to navigate to the printed http address. The website will have a Debug button, or you can just append `/debug.html` to the url like so: `http://localhost:9876/debug.html` (your port may vary).\n\nIn debug mode, you can see all console logs in Chrome's own DevTools, you can use `debugger;` statements, etc.\nBehind the scenes, Karma runs a webpack dev server in watch mode, which means if you change the source code, webpack will recompile and karma will attempt to re-run the tests. If the tests do not rerun for some reason, just navigate to `http://localhost:9876/debug.html` again.\n\n(I recommend opening DevTools before navigating to `/debug.html` to make sure you don't miss `debugger;` statements and see the console output even if a test hangs the browser or enters an infinite loop.)\n\n### Browser tests failing to run with `Error: spawn Unknown system error -86`\n\nThis is most likely because the browser tests are trying to run a headless version of Chrome built for Intel chips on an Mac with an ARM chip. If that's the case, [Rosetta 2](https://support.apple.com/en-gb/HT211861) should solve your problem:\n\n```\nsoftwareupdate --install-rosetta\n```\n\n## VSCode linting, formatting with prettier etc\n\nTo enable format-on-save, you should install the VSCode plugin `esbenp.prettier-vscode`, and `dbaeumer.vscode-eslint` and then in your workspace settings, enable format on save, and tell prettier to use the eslint integration mode:\n\n```\n  \"eslint.workingDirectories\": [\"./editor\", \"./utopia-api\"],\n  \"editor.formatOnSave\": true,\n  \"prettier.useEditorConfig\": false,\n  \"prettier.requireConfig\": true,\n  \"[typescript]\": {\n    \"editor.defaultFormatter\": \"esbenp.prettier-vscode\"\n  },\n  \"[javascript]\": {\n    \"editor.defaultFormatter\": \"esbenp.prettier-vscode\"\n  },\n  \"[typescriptreact]\": {\n    \"editor.defaultFormatter\": \"esbenp.prettier-vscode\"\n  },\n  \"[json]\": {\n    \"editor.defaultFormatter\": \"esbenp.prettier-vscode\"\n  }\n\n```\n\nSelect prettier as the default formatter in your settings; VSCode may prompt you to do so. The last four line items, starting with `[typescript]` reflect this. You should restart VSCode after this.\n\n# Deploying\n\nAll pushes to the `master` branch will immediately trigger [this](.github/workflows/master-pushes.yml) workflow that runs the tests and then triggers a deploy to our Staging environment.\n\nTo deploy to the Production environment, somebody needs to manually trigger our [`tag-release.yml`](.github/workflows/tag-release.yml) workflow, giving either a specific commit hash or branch name (defaulting to `master`), and optionally a tag name (the default behaviour is to increment the patch version). This can be triggered via the \"Run Workflow\" button [here](https://github.com/concrete-utopia/utopia/actions?query=workflow%3A%22Tag+and+Release%22)  \n**Note**: in the \"Use workflow from\" dropdown you have to select \"Branch: master\" - this is specifying which workflow to run, not which branch to cut the release from.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fconcrete-utopia%2Futopia","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fconcrete-utopia%2Futopia","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fconcrete-utopia%2Futopia/lists"}