Introducing Elm Editor - a web-based IDE for Elm programs

Hi everyone,

This is an overview of Elm Editor, a project I have been working on for about a year now.

Elm Editor is a web app for developing Elm programs.

As an integrated development environment, it assists us in reading, writing, and testing Elm programs and in collaborating with other developers.

This project minimizes the friction for newcomers to get started with programming. Since the front-end is entirely web-based, it requires practically no setup. Any modern web browser is enough to use it.

To see Elm Editor in action, check out the public instance at https://elm-editor.com

This video is a short demonstration of a code editing cycle in Elm Editor:

Features in 2021

Some of the features come for free with the Monaco Editor. Others required more effort and glue code in javascript to communicate with and synchronize with the code editor. (Learned quite a bit about javascript in this project)

  • Viewing and editing all Elm module files as well as other text files in your project.
  • Checking programs for problems such as Elm compiler errors.
  • Saving and sharing the current state of a project, including all files.
  • Importing complete projects from public git repositories.
  • For front-end web apps, viewing and testing the app in an iframe.
  • Visual markers in the code to quickly find locations of problems.
  • Showing error descriptions on mouse hover.
  • Completion suggestions to discover available declarations and explore useful codes.
  • Showing documentation and details when hovering the mouse cursor over a part of the code.
  • Command palette to discover new functionality and keyboard shortcuts.
  • Text search with options for case sensitivity, regular expressions, and replacing matches.

Besides these features also found in traditional big desktop-based IDEs, there are more innovative features like the differential project state model.

Project Organization and Implementation

Elm Editor is an open-source project organized for easy customization and deployment of custom instances. The source code lives at elm-fullstack/implement/example-apps/elm-editor at main · elm-fullstack/elm-fullstack · GitHub

Most of the action happens in the front-end. The primary role of the back-end is integrating tools like the Elm and elm-format executable files and interfacing with Git hosting services like GitHub and GitLab.

The front-end is mainly written in Elm and integrates the Monaco Editor from the VS Code project. The Elm app implements ports with the javascript-based Monaco Editor. The Elm side also implements language services that power editor features that require understanding the syntax and semantics of the Elm programming language.

Outlook

Development continues to make reading and developing Elm programs even more efficient. Integration of a test runner seems one of the more obvious things to add soon. Adding a REPL seems another great addition. A REPL is a more interactive alternative for testing and exploring the behavior of the code in the current workspace.

Then there are more minor improvements like a preview for Markdown files and viewers for images and audio files (for those working on video games).

There are tons of ideas for new features; I could probably go on for hours. As with my other open-source projects, prioritization depends in large part on your feedback. Besides the Elm discourse, a good place for discussion and feedback is on GitHub at Discussions · elm-fullstack/elm-fullstack · GitHub or in the issues section.

35 Likes

@Viir, wow, this is impressive!

I haven’t gone through all the feture yet, but I have a quick question. Can I use my own HTML? I could not figure it out (I need to have ports and flags).

2 Likes

We can distinguish two different kinds of using ‘own HTML’: One is when you customize Elm Editor itself. That already works well.

I guess you had instead in mind the live view functionality for frontend apps. The built-in view does not yet support custom HTML.

Most people used it for non-frontend projects anyway, and there had not been a use-case for custom HTML so far.
Now that you mention it, I think it would be a good addition.

If you have a project you want to see supported, I am happy to discuss what UI or API we could use here.

1 Like

I was thinking about editing HTML similarly to Ellie.

This is a small example that generates an error due to the missing Flags.

2 Likes

Thank you for the example. I will use that for testing.

As far as I see, we would need to add some code to declare a relation between custom HTML and the Elm app.

I don’t know how it would work in Ellie. If there is an example, I will take a look.

I will experiment and look for an API for merging HTML and the Elm app.


EDIT:

Looks like I found one solution. I illustrated one idea of how that additional code could look here:

The idea is to have the development tool interpret a declaration as an entry point/root if the declaration name is htmlMain.
The editor could take the value out of this declaration and forward it to the HTML preview.

I have not yet tested if the formatting/escaping in the script tag is complete.

This example (re)uses existing APIs for Fullstack App development to integrate Elm make and read from source files.
Usage of the CompilationInterface.ElmMake interface is documented at elm-fullstack/how-to-configure-and-deploy-an-elm-fullstack-app.md at 78243a5db8349186698d3aecdd4ac7c83496a0e0 · elm-fullstack/elm-fullstack · GitHub

1 Like

Hello

Congratulations for this project, it’s great!

I know it would be quite a big deal, but the feature which would provide me an even greater value would be collaborative editing. It would allow using Elm Editor for (remote) pair or mob programming. That would be especially useful for training workshops. I’m using glitch.com for this until now, but the Elm integration is as limited (no elm format, no elm-test, compiler output not immediately visible…) as the editor itself.

3 Likes

Amazing! Thanks for that :+1:

Ellie (https://ellie-app.com/new) has an HTML page that is used to load and run the Elm application (bottom left corner). So it is possible to add flags and communicate with ports there.

@PascalLeMerrer thanks for the input, it sounds interesting. I want to learn what that means and how you do mob programming. I have not yet seen such a feature in glitch. I consulted Wikipedia on the topic and found this:

Mob programming (informally mobbing) (aka. ensemble programming) is a software development approach where the whole team works on the same thing, at the same time, in the same space, and at the same computer. This is similar to pair programming where two people sit at the same computer and collaborate on the same code at the same time.

That sounds like we don’t need to merge inputs coming from multiple users at the same time. Is that correct?

I think such a constraint could simplify an implementation a lot compared to more permissive models. So I wonder if such a constraint would fit in your training workshops.

What do you think of a solution where a user has to release control over the IDE explicitly, or the trainer has to assign control of the IDE explicitly?

Would that slow you down?
Would that be worse than your current solution with glitch?

As far as I see, Ellie has some distinct properties:

  • It limits the project to a single HTML file.
  • It limits the project to a single Elm module.

When you use the Compile function, these constraints make it possible to guess automagically:

  • Which HTML file do you want to use.
  • Which Elm module do you want to use.

However, in Elm Editor, I see none of these constraints.
What can we do in the absence of these guarantees?
Maybe we can find smarter magic to guess the user’s intent? I don’t know if that is possible, but if anybody has an idea, I’d be interested to see it.
But we don’t have to rely on that route. An alternative solution is to offer the user an interface to express their intent.

Would that work for the usage you have in mind?

It already works similarly for choosing the Elm module that to compile. Since there can be multiple Elm module files, the users already have to decide here one way or another.

Asking users to make such a choice is a tradeoff:

  • Advantage: The flexibility means supporting a wider range of use cases.
  • Disadvantage: In simpler scenarios, it slows users down.

Elm Editor has a design to mitigate that downside: Trainers can make these choices and encode them in the link or project state they hand out to students.

We already use this kind of mitigation for the decision of which file to open: Trainers can include this choice in a link. When a user follows such a link, the system opens that file on initialization. It is just automating what would have happened if the user had made that choice manually.

@viir : Glitch allows multiple persons to modify the code simultaneously. However, you’re totally right, it’s not a requirement for mob programming. As long as you can give easily the control from one participant to another, that’s OK.

1 Like

How about a configuration file (elm-editor.json?) that itself can be included in the repo? For example:

{
    "dir":        "/",            // The base for static content (default: "/")
    "start-page": "/index.html"   // Specify a custom HTML file (default: "/index.html")
    "output":     "/index.js"     // Specify the name of the compiled JS file (default: "/index.js")
    "optimize":   false           // Turn on optimizations to make code smaller and faster (default: false)
    "debug":      false           // Turn on the time-travelling debugger (default: false)
    etc.
}

For static content, it could be possible to leverage “GitHub Pages”

1 Like

Matthew Weidner talking about adding collaboration to single-user apps :sweat_smile: :

In the single user case, you could just make it in the weekend, put it up and forget about it.

Basically at this point, you are thinking of quiting your job and starting a startup, all just to add collaboration to this app.

This is from his talk in the Strange Loop conference: “Making Webapps Collaborative with Composable CRDTs”

3 Likes

I’m impressed @Viir at what you’ve done. I’ve a couple of comments on collaborative editing (based on what I’ve read, not on personal experience).

I read this recent article on Jamstack (JavaScript, APIs and Markup) that said

Another notable statistic is that these developers largely use Figma for designing user interfaces and are happy with it, awarding it by far the highest scores for both usage and satisfaction. Adobe XD (Experience Design) was second but a long way behind.

I hadn’t heard of Figma before. Here’s the wikipedia article which says

Figma focuses on use in user interface and user experience design, with an emphasis on real-time collaboration.

I don’t have any conclusions, except that there’s interesting stuff happening both inside and outside the Elm community.

Yes, that looks like it works to select an Elm module and an HTML file.

So when the user presses the Compile button while that JSON file is open, we apply the merging for custom HTML.
Is that the user interface that you had in mind?

For context: The action triggered by the compile button takes into account the currently open file.
With the current implementation, the compile action only works when the open file’s name ends in .elm. The compile function is not defined so far for files with names ending in .json like the proposed one.

This screenshot shows the warning message in today’s implementation to remind users that the file they compiled last is not the same they are currently viewing/editing:

My expectation is that every time I press the compile button, the main Elm file (specified in the JSON file) is compiled and the HTML page somehow refreshed.

I don’t expect any other sub Elm file to be compiled independently, at any time.

1 Like

Thank you for clarifying, I was unaware of that, and that expectation makes a big difference. Such a user interface would mean stopping support for some projects.

Elm Editor supports projects with multiple entry points, including browser apps.

When working on games, I use additional browser apps for faster interactive testing.

Another example using multiple entry points is the elm-3d-playground-exploration by @Erkal_Selman: https://elm-editor.com/?project-state=https%3A%2F%2Fgithub.com%2Ferkal%2Felm-3d-playground-exploration%2Ftree%2F022ae72a427ecbf8c9b7bb0e4c608c5d195c2546%2F

I prefer Elm Editor to continue supporting these projects. When adding support for custom HTML, I will use a design that does not require sacrificing this support.

2 Likes

@Viir Nice work! I’ve been waiting for an eternity for an online editor that could handle online (github) repos as a link. This is a huge leap forward!
Some little remarks, if you allow:

  • Link parsing intelligence: I was going too fast and oversaw that the link has to be a tree. I don’t know if this would be hard to implement but some kind of dialog “I’ve seen you want to get this repo, should i fetch the master tree?” would make the experience even smoother.
  • Refresh-resistance: Another convenience feature I would celebrate would be to encode the repo link into the URL and then load it on page load. This seems to be way harder to implement, but would be a real game changer for me!

Nevertheless, splendid work! Having an eye on the development :slight_smile:

1 Like

Great idea to remove a potential stumbling block! Now that you mention it, I see the benefit of supporting the URL from the repository home/landing page.

Regarding the implementation and design: As far as I see, GitHub allows for different names for the main branch, so we cannot just insert ‘main’ as the branch name.
If we want to show that dialog instead of silently substituting the main branch, this might imply an additional API call to get the branch name (if we’re going to display the branch name or the commit).

Overall I don’t think it will be hard to implement.

Good to know. That was easy to understand, makes sense to me, so I went and implemented it here:

To summarize the changed behavior:

  • When you are in the dialog to load from Git and use the button to confirm the new project state: The system updates the URL so that you’d land in the same project state if you let the browser refresh the page.
  • When you are in the dialog to import from a zip archive and use the button to confirm the new project state: The system resets the URL in the address bar to clarify that the current state is not based on a Git repo anymore.

Now that’s what I call rapid development! :+1:
Bonus points for the open communication :wink: