vite-plugin-elm-watch
🚨 Warning: This plugin is still experimental, and doesn't quite work as intended. Publishing here to share progress and work through minor bugs!
Use Vite and Elm with reliable HMR and full-color error messages!
Installation
npm install -D vite-plugin-elm-watch
Usage
import { defineConfig } from 'vite'
import elm from 'vite-plugin-elm-watch'
export default defineConfig({
plugins: [elm()]
})
import Main from './src/Main.elm'
let app = Main.init()
Features
- Import
*.elm
files directly from JavaScript or TypeScript
- Reliable HMR powered by elm-watch
- Full-color, friendly compiler messages in the browser
- Jump to problem from your browser in one click
- JS minification step is included
- React output mode for easy interop with existing components
Screenshots



Options
mode
When using the official Elm CLI, you have access to flags that can add Elm's time-traveling debugger, or optimize your code for production.
This plugin also adds a few additional options for minifying compiled code for production and provides nice defaults in development.
'auto'
| 'standard'
| 'debug'
| 'optimize'
| 'minify'
output
'default'
| 'react'
This option allows you to specify what your imported Elm code will return. For React apps, we recommend using the 'react'
output so you can easily swap .jsx/.tsx
files with .elm
and things will just work ™️.
Warning: Still working through HMR bugs before this is production ready!
isBodyPatchEnabled
isBodyPatchEnabled : boolean
In production, you might encounter issues caused by third party JS that modify the <body>
element. This only is a problem for folks using Browser.application
, which expects control over the entire <body>
element.
By enabling isBodyPatchEnabled: true
, you'll be able to specify a custom root node. This uses Elm's standard node
field when initializing the app:
import Main from './src/Main.elm'
let app = Main.init({
node: document.getElementById('elm_root')
})
Note: This will only work if the element has an id
attribute.
A known issue is that Elm will clear out attributes for this root element, so id="elm_root"
won't be visible after Elm loads.
Known issues
- When in a React app, swapping a ".elm" component with a ".tsx" will causes issues with unmounting.
- React calls
removeChild
internally on the initial DOM node, before our component can run app.unmount()
. This leads to a runtime exception!