[ANN] Lit.jl — A Simple, Data-Centric Web App Framework for Julia

:rocket: Lit.jl — A Simple, Data-Centric Web App Framework for Julia

NOTE: Currently supported platform: Linux x86_64 (which also works on WSL)

Hi everyone,

I’m happy to introduce Lit.jl, a new Julia web app framework designed to make it easy for scientists, researchers, and data practitioners to build interactive web applications without requiring frontend experience.

:backhand_index_pointing_right: Live Demos: https://lit.coisasdodavi.net/
:backhand_index_pointing_right: Documentation: https://lit.coisasdodavi.net/docs/build/docs/getting-started/install
:backhand_index_pointing_right: Repository: https://github.com/nidoro/Lit.jl

:brain: What Lit.jl Is

Lit.jl takes inspiration from frameworks like Streamlit for Python, but is built specifically for the Julia ecosystem. It lets you write Julia scripts that become interactive web apps — with simple UI elements, reactive behavior, and minimal boilerplate.

  • No frontend skills needed
    You build your app purely in Julia; Lit handles the UI and web server.
  • Scripting-first model
    Apps are just Julia scripts that run from top to bottom on interaction — familiar and predictable.
  • Data-centric design
    Built for data workflows, dashboards, and exploratory interfaces that combine computation and UI.
  • Fast iteration
    Changes reload quickly, letting you iterate on app logic and layout without heavy overhead.

:light_bulb: Why Lit.jl?

Julia has many strengths for numerical computing and modeling, but simple interactive apps have traditionally required stitching together web frameworks or external tools.

Lit.jl aims to fill that gap with:

  • a minimal, familiar API
  • a design that prioritizes exploratory data interaction
  • no need to write HTML/CSS/JS to get useful applications running

It’s a solid choice for dashboards, demos, teaching tools, or lightweight GUIs for analysis.

:megaphone: Come Try It, Give Feedback

Let us know what you think! Feel free to open issues here: https://github.com/nidoro/Lit.jl/issues

32 Likes

Nice work!

Here with clickable links:

Live Demos: https://lit.coisasdodavi.net/
:backhand_index_pointing_right: Documentation: https://lit.coisasdodavi.net/docs/build/docs/getting-started/install
:backhand_index_pointing_right: Repository: https://github.com/nidoro/Lit.jl

However, it is challenging to set up a server that runs Julia securely.

8 Likes

@nidoro very nice! Are you planning to register Lit.jl?

Yes I am. I gotta take some time to look into that. I believe I will need some permission, never gonne through the process.

1 Like

No permission required. You only need to follow the rules, like naming of your package and defining the minimal and maximal version of your dependencies in your Project.toml.

4 Likes

Impressive! The demo is a little bit laggy, even when change to the page with a simple control. I don’t know whether it is caused by the server or the ttfx of julia?

3 Likes

That’s probably the server. It is located here in Brazil, and it is also really limited, with 2GB of RAM and 2 cores.

3 Likes

One of which:

The name is at least 5 characters long.

As you’ll have to rename the package for registration anyway, it might be better to give it a descriptive name.

3 Likes

Where did you find the rule that the package name has to be at least 5 characters long? I could not find it at 5. Creating Packages · Pkg.jl .

Sorry, forgot to add the link:

Yeah, I found out about that when I tried to register it yesterday. Sad. At this point it’s just too much work to change the name on everything: repo, source code, prefixes, website, logos, docs, demos, tutorial, domain names, paths and folders. It is not a small project. And I would rather focus on other things, so I guess I’ll just stay out of General.

1 Like

Well, it would be sufficient to change the name of the repository. And that is less than 5 minutes of work. And in the documentation, that is just search-and-replace.

Finally, you can also register a package with a shorter name. It just does not work automatically; you can request a manual exception from the maintainer.

The chance that many people will use your package is much higher if it is registered.

7 Likes

Actually, as of Nov 2025, and at least as far as 3-letter names are concerned, the minimum package name length is a hard rule.

3 Likes

Not really. You just need to put it in a container and use a reverse proxy. These sorts of web interfaces should not accept arbitrary code, so user input is automatically sanitized. I have some examples in this article: https://www.digitalocean.com/community/tutorials/web-applications-with-julia

6 Likes

Indeed. At the end of the day, regardless of the language or framework used, the security of a web app depends mostly on what the web app does with user input.

Setting up a container and reverse proxy can help to reduce the surface and effectiveness of potential attacks, but I surely don’t think they are a requirement for making machines hosting Lit web apps safe. That’s because Lit by itself does not do much with user input. It handles HTTP(S) and WS(S) headers and path input to do basic routing and file serving, but does almost nothing with actual input entered via widgets, aside from parsing it to keep track of widget states. Then it exposes widget states to the app’s script. What happens after that is up to the developer of the app.

In summary, developers concerned with security can take all measures that they want to protect the host machine, but these measures are not strictly required to safely host a Lit app. The most important thing is that they don’t use unsanitized user input in an unsafe manner, like try to eval it or use it to open server-side files or something crazy like that.

I think it’s not that simple. For example you need some extra protection against large POST request bodies, to prevent DOS. If you process request via HTTP.jl, but don’t use a reverse proxy. Right?

However, thank you for Lit.jl and for extending the Julia Web ecosystem further!

BR Stefan

3 Likes

A DOS attack, alone, is not a safety threat. The most it can do is to, well, deny service. Sure, developers that worry about this threat will need mechanisms to prevent that from happening, but that does not make your website safer, just more resilient. Besides, if you are using hosting services like AWS, Google or Azure, they all have built-in mechanisms to defend their servers from DOS attacks. And if you are hosting it in an internal network, like in a comany, you most likely don’t have to worry about that.

And about what Lit uses for network, I don’t use HTTP.jl. The network layer of Lit is implemented in C++ and it uses libwebsockets for both HTTP and WS.

I think you confuse the general concept of “denial of service” (DOS) attacks with the more specific “distributed denial of service” (DDOS). A basic DDOS protection might be there for many Cloud hosted services, but the issue I described with HTTP.jl (if you don’t take any additional measures) doesn’t require a DDOS. A single malicious HTTP POST request can take out the server, and most Cloud service providers will not protect you against this, by default.

When you wrote “… security of a web app …” I thought in terms of information security. Information security is not just about data confidentiality and integrity but also availability (aka CIA Triad). That’s why I mentioned the specific HTTP.jl DOS threat, for which I think a reverse proxy is a simple and effective countermeasure.

But since Lit.jl is based on libwebsockets, as you explained, this might no apply to it.

BR Stefan

2 Likes

You are right, I was mostly thinking about DDOS. I see how a single maliciously crafted or large request can maybe take down a server. Still have to implement tests for that, though. Thanks for the heads up.

2 Likes

:rocket: v0.2.4 (2026-01-10) - Windows 64 bit Support

  • Added Windows 64-bit support.
  • Brazil’s temperature forecast example now downloads the shape file if it doesn’t exist.
  • Bug-fix: rerun requests are now serialized in the back and front-ends.
  • Bug-fix: implemented proper paste behaviour for dataframe.
3 Likes