{"id":20310814,"url":"https://github.com/progrium/env86","last_synced_at":"2025-10-08T21:12:26.478Z","repository":{"id":251262562,"uuid":"836885051","full_name":"progrium/env86","owner":"progrium","description":"Embeddable v86 virtual machines","archived":false,"fork":false,"pushed_at":"2025-01-02T21:44:42.000Z","size":36582,"stargazers_count":47,"open_issues_count":8,"forks_count":4,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-09-12T18:29:28.214Z","etag":null,"topics":["emulator","virtualization","wasm","x86"],"latest_commit_sha":null,"homepage":"","language":"Go","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/progrium.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"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,"zenodo":null}},"created_at":"2024-08-01T18:58:37.000Z","updated_at":"2025-09-07T20:36:53.000Z","dependencies_parsed_at":"2024-11-14T17:36:17.779Z","dependency_job_id":"a5a37077-450f-4d16-ace4-92c16f168395","html_url":"https://github.com/progrium/env86","commit_stats":null,"previous_names":["progrium/env86"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/progrium/env86","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/progrium%2Fenv86","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/progrium%2Fenv86/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/progrium%2Fenv86/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/progrium%2Fenv86/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/progrium","download_url":"https://codeload.github.com/progrium/env86/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/progrium%2Fenv86/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279000715,"owners_count":26082837,"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","status":"online","status_checked_at":"2025-10-08T02:00:06.501Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["emulator","virtualization","wasm","x86"],"created_at":"2024-11-14T17:34:37.526Z","updated_at":"2025-10-08T21:12:26.459Z","avatar_url":"https://github.com/progrium.png","language":"Go","readme":"# env86\n\nEmbeddable virtual machines based on the [v86](https://github.com/copy/v86) emulator.\n\n## Features\n\n* Run, author, and debug web embeddable VMs via CLI tool\n* Network VMs with full virtual network stack\n* Prepare HTML assets for easy deploying to static hosts\n\n\n## Getting Started\n\nYou can build env86 using Go, but the static assets it bundles are set up with Docker. With both installed,\nand a cloned repo, you can run:\n\n```sh\nmake all\n```\n\nThis will use Docker to create some static assets like [v86](https://github.com/copy/v86),\nthen it will use Go to compile `env86` and write the executable to the current directory. Move this into your `PATH` or you can run `./env86` and get:\n\n```\nUsage:\nenv86 [command]\n\nAvailable Commands:\nboot             boot and run a VM\nprepare          prepare a VM for publishing on the web\nnetwork          run virtual network and relay\nserve            serve a VM and debug console over HTTP\ncreate           create an image from directory or using Docker\n\nFlags:\n  -v    show version\n\nUse \"env86 [command] -help\" for more information about a command.\n```\n\n### Creating Images\n\n`env86` images are directories or tarballs with an `image.json` file and some v86 specific files\nfor the filesystem and initial state. With the `create` subcommand you can make an image from a Linux root directory\nor using Docker, either an image to pull or a Dockerfile to build. Here's a Dockerfile to make an\nAlpine Linux image:\n\n```Dockerfile\nFROM i386/alpine:3.18.6\nRUN apk add openrc agetty\nRUN sed -i 's/getty 38400 tty1/agetty --autologin root tty1 linux/' /etc/inittab\nRUN echo 'ttyS0::once:/sbin/agetty --autologin root -s ttyS0 115200 vt100' \u003e\u003e /etc/inittab \nRUN echo \"root:root\" | chpasswd\n``` \n\nThe v86 emulator is 32-bit x86, so this is a 32-bit based Alpine. Any Docker commands run are run with\n`--platform=linux/386` behind the scenes, so always keep this in mind when making images. We can build this\nimage and write it to `./alpine-vm`:\n\n```sh\nenv86 create --from-docker=./path/to/Dockerfile ./alpine-vm\n```\n\n### Booting VMs\n\nOnce we have an env86 image, we can boot it. Booting has the most options:\n\n```\nUsage:\nenv86 boot \u003cimage\u003e\n\nFlags:\n  -cdp\n        use headless chrome\n  -cold\n        cold boot without initial state\n  -console-url\n        show the URL to the console\n  -n\n        enable networking (shorthand)\n  -net\n        enable networking\n  -no-console\n        disable console window\n  -no-keyboard\n        disable keyboard\n  -no-mouse\n        disable mouse\n  -p string\n        forward TCP port (ex: 8080:80)\n  -save\n        save initial state to image on exit\n  -ttyS0\n        open TTY over serial0\n```\n\nWe can boot our Alpine VM with `--save` so we can skip cold booting in future boots:\n\n```sh\nenv86 boot --save ./alpine-vm\n```\n\nThis should pop open a window showing the screen console (though please submit an issue if this isn't\nworking on Windows or Linux). Once it gets to the shell, at the terminal we can hit `Ctrl+D` to send EOF,\nwhich terminates the VM, but with `--save` it will first save the current state to the initial state of the image.\n\nNow if we boot again, it should restore back to the prompt we ended it at. If we ever don't want this,\nwe can pass `--cold` to cold boot without restoring initial state.\n\nWe can also boot without the console window and just interact with the VM via ttyS0 in the terminal:\n\n```sh\nenv86 boot --ttyS0 --no-console ./alpine-vm\n```\n\n### Publishing VMs\n\nOnce an image is in a state you want to share and you want to make it run on the web, you can use `prepare` to \ngenerate all the static files needed to serve this VM over HTTP:\n\n```sh\nenv86 prepare ./alpine-vm www\n```\n\nThis will make a `www` directory with an example `index.html` and all the files that need to be served over\nHTTP to run this VM in the browser including the `v86.wasm` file. The image files are slightly different when prepared, splitting the initial state into 10MB parts for more efficiently loading over the web.\n\n### Networking\n\nIf you boot with `--net` a virtual network stack and switch is created and wired up to the VM virtual NIC that will forward packets to your host computer network. The guest image will need to have network drivers and then be configured *after* booting to use the Internet. Here is a Dockerfile to make an env86 image that has a `./networking.sh` script to run after\nbooting to use the network provided by `--net`:\n\n```Dockerfile\nFROM i386/alpine:3.18.6\n\nENV KERNEL=lts\nENV HOSTNAME=localhost\nENV PASSWORD='root'\n\nRUN apk add openrc \\ \n            alpine-base \\\n            agetty \\\n            alpine-conf\n\n# Install mkinitfs from edge (todo: remove this when 3.19+ has worked properly with 9pfs)\nRUN apk add mkinitfs --no-cache --allow-untrusted --repository https://dl-cdn.alpinelinux.org/alpine/edge/main/ \n\nRUN if [ \"$KERNEL\" == \"lts\" ]; then \\\n    apk add linux-lts \\\n            linux-firmware-none \\\n            linux-firmware-sb16; \\\nelse \\\n    apk add linux-$KERNEL; \\\nfi\n\n# Adding networking.sh script (works only on lts kernel yet)\nRUN if [ \"$KERNEL\" == \"lts\" ]; then \\ \n    echo -e \"echo '127.0.0.1 localhost' \u003e\u003e /etc/hosts \u0026\u0026 rmmod ne2k-pci \u0026\u0026 modprobe ne2k-pci\\nhwclock -s\\nsetup-interfaces -a -r\" \u003e /root/networking.sh \u0026\u0026 \\ \n    chmod +x /root/networking.sh; \\ \nfi\n\nRUN sed -i 's/getty 38400 tty1/agetty --autologin root tty1 linux/' /etc/inittab\nRUN echo 'ttyS0::once:/sbin/agetty --autologin root -s ttyS0 115200 vt100' \u003e\u003e /etc/inittab \nRUN echo \"root:$PASSWORD\" | chpasswd\n\n# https://wiki.alpinelinux.org/wiki/Alpine_Linux_in_a_chroot#Preparing_init_services\nRUN for i in devfs dmesg mdev hwdrivers; do rc-update add $i sysinit; done\nRUN for i in hwclock modules sysctl hostname bootmisc; do rc-update add $i boot; done\nRUN rc-update add killprocs shutdown\n\n# Generate initramfs with 9p modules\nRUN mkinitfs -F \"ata base ide scsi virtio ext4 9p\" $(cat /usr/share/kernel/$KERNEL/kernel.release)\n```\n\nThen we can run:\n\n```sh\nenv86 create --from-docker=./path/to/Dockerfile ./alpine-net\nenv86 boot --net --save ./alpine-net\n```\n\nAt the prompt we can run `./networking.sh` and it should get an IP and be able to connect to the Internet. \n\nWe can use networking from the browser if we add `network_relay_url` to the config passed to `env86.boot()` in `index.html`. We can run `env86 network` to start a virtual network and get a URL to use for `network_relay_url`. \n\n### More Features\n\nA few more features are tucked away or are in progress. The next major focus is on a standard guest service\nfor Linux VMs that will open up more functionality in `env86` like Docker-style `run` and `build` commands,\nmounting local directories in the VM, and more.\n\n### Using as a Library\n\nThe `env86` command line tool is a wrapper around a Go library you can use to work with and run VMs in regular\nGo programs outside the browser. \n\n\n## Thanks\n\nThis project was made possible by [my sponsors](https://github.com/sponsors/progrium) but also the amazing work of the [v86](https://github.com/copy/v86) team. Also thanks to Joël and Adam for introducing me to v86.\n\n## License\n\nMIT","funding_links":["https://github.com/sponsors/progrium"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprogrium%2Fenv86","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fprogrium%2Fenv86","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprogrium%2Fenv86/lists"}