Show HN: Marimo – an open-source reactive notebook for Python (github.com)
GitHub repo: https://github.com/marimo-team/marimo
In marimo, a notebook’s code, outputs, and program state are always consistent. Run a cell and marimo reacts by automatically running the cells that reference its declared variables. Delete a cell and marimo scrubs its variables from program memory, eliminating hidden state. Our reactive runtime is based on static analysis, so it’s performant. If you’re worried about accidentally triggering expensive computations, you can disable specific cells from auto-running.
marimo comes with UI elements like sliders, a dataframe transformer, and interactive plots that are automatically synchronized with Python [3]. Interact with an element and the cells that use it are automatically re-run with its latest value. Reactivity makes these UI elements more useful and ergonomic than Jupyter’s ipywidgets.
Every marimo notebook can be run as a script from the command line, with cells executed in a topologically sorted order, or served as an interactive web app, using the marimo CLI.
We’re a team of just two developers. We chose to develop marimo because we believe that the Python community deserves a better programming environment to do research and communicate it; experiment with code and share it; and learn computational science and teach it. We’ve seen lots of research start in Jupyter notebooks (much of my own has), only to fail to reproduce; lots of promising prototypes built that were never made real; and lots of tutorials written that failed to engage students.
marimo has been developed with the close input of scientists and engineers, and with inspiration from many tools, including Pluto.jl and streamlit. We open-sourced it recently because we feel it’s ready for broader use. Please try it out (pip install marimo && marimo tutorial intro). We’d appreciate your feedback!
[1] https://github.com/marimo-team/marimo
109 comments
[ 4.7 ms ] story [ 407 ms ] threadhttps://docs.marimo.io/faq.html#faq-jupyter
This does to address directly the second problem. It does however by sacrificing flexibility. I might need to change a cell just to test a new thing (without affecting the other cells) but thats a trade off if you focus on reproducibility.
I know that requirements.txt is the standard solution to the other problem. But generating and using it is annoying. The command pio freeze will list all the packages in bloated way (there is better ways) but I always hoped to find a notebook system that will integrate this information natively and have a way to embed that into a notebook in a form that I can share with other people. Unfortunately I can't see support for something in any of the available solutions (at least up to my knowledge).
It's a bit challenging because Python has so many different solutions for package management. If you have any ideas we'd love to hear them.
I don't think this is really a solution, not to mention that this raise the question. Does it support running shell commands using '!' like Jupyter Notebook?
Does that align with what you're talking about?
That page has some scrawled brainstormed notes. But we haven't spent time designing a solution yet.
And it does not account for dependincies version conflicts which life very hard.
If you have conflicts then you have to reconcile those at point of initial install - pip deals with that for you. I’ve never had a situation in 15 years of Python packages where there wasn’t a working combination of versions.
These are genuine questions btw. I see these common complaints and wonder how I’ve not ever had issues with it.
1- pip freeze will miss packages not installed by pip (i.e. Conda).
2- It does include all packages, even not used in the project.
3- It just dumps all packages, their dependencies and sub-dependencies. Even without conflicts, if you happen to change a package, then it is very hard to keep track of dependencies and sub-dependencies that need to be removed. At some point, your file will be a hot mess.
4. If you install specific platform package version then this information will not be tracked
If I want to install something, I pip install and then add the explicit version to the base. I can then freeze the current state to requirements to lock in all the sub dependencies.
It’s a bit manual (though you only need a couple of cli commands) but it’s simple and robust.
But if someone is coming from data science and not dev-ops then no matter how much we say “all you have to do”. The response will be why do I have to do any of this?
How does it handle the problem?
2/3- you need to track only the direct dependencies _manually_ but for reprodicible deployments you need fixed versions for all dependencies. The latter is easy to generate _automatically_ (`pip freeze`, pip-tools, pipenv/poetry/etc).
3 is solved by the workflow of manually adding requirements and not including dependencies. It may not work for everyone. Something like pipreqs might work for many people.
I do not understand why 4 is such a problem. Can you explain further?
After trying to migrate everything to pipenv and then getting burned, I went back to this and can't imagine I'll use another third-party packaging project (other than nix) for the foreseeable future.
And even if it’s on some shared storage, it may have been generated by another unreproducible notebook or worse, manually.
It comes with costs and the gpu-related stuff is especially tricky e.g. https://www.canva.dev/blog/engineering/supporting-gpu-accele...
Have you looked into WASM? Something like a jupyterlite [0] alternative for marimo?
And are there plans to integrate linting and formatting with ruff? [1]
[0] https://jupyterlite.readthedocs.io/en/stable/
[1] https://github.com/astral-sh/ruff (ruff format is almost 100% compatible with black formatting)
A ruff integration is a great idea. I'll add it to the roadmap.
I see some package management stuff on the roadmap.
Maybe you could take a look at the cargo cli, like pixi did [0]. IMO it's a nice user experience.
[0] https://prefix.dev/
</2 cents>
Having an excellent cache might reduce spurious re-running of cells, but I wonder if it would be sufficient.
We also let users disable cells (and their descendants), which can be useful if you're iterating on a cell that's close to the root of your notebook DAG: https://docs.marimo.io/guides/reactivity.html#disabling-cell...
Would be cool if we could come up with a standard that works across notebooks / libraries!
Unfortunately, I'm quite used to very specific vim keybindings in Jupyter (https://github.com/lambdalisue/jupyter-vim-binding) that make it pretty hard to use anything else :/
(Neovim user myself, as much as I dislike vscode for everything else, as of now it's hard to replace it when using jupyter)
https://soltech.com/blogs/blog/how-to-care-for-your-marimo-m...
Marimo kind of takes the reactive widgets of streamlit and brings them back into a notebook-like UI, and provides a way to export the notebooks into shareable apps.
You've solved that incredibly well!
I also really like that the Marimo file format is just Python. Here's an example saved file from playing around with the intro: https://gist.github.com/simonw/e6e6e4b45d1bed9fc1482412743b8...
Nice that it's Apache 2 licensed too.
Wow, I just found the GitHub Copilot feature too!
We are thrilled to see you have such a strong positive reaction. It means a lot coming from you - I initially learned web development using Django and landed my first contracting gig with Django.
I drifted away from writing Python and towards Typescript - but marimo has brought me back to writing Python.
Have you had anyone use Marimo to write production web app code? I've been doing a lot of AI experiments for the new venture, and it's been a pain to have to switch back and forth between .ipynb files and regular py files
Our friends at SLAC use marimo for their internal exploration experiments and publishing interactive apps. He is an example: https://marimo.io/@public/signal-decomposition
I'm a big fan of your work, and as I've learnt a lot from reading your blog posts over the years, I'd be curious to know a bit more about typical use cases for wanting to work with Observable notebooks.
The only reason why I'm using A JavaScript notebook tool (Starboard.gg) is to be able to access cool visualisation packages like Anychart or Highcharts.
Given the hype around Observable notebooks, I feel that I'm missing something.
What makes you decide to start something in an Observable notebook rather than in Jupyter?
Thanks!
Here are some of my Observable notebooks which illustrate the kind of things I use it for:
https://observablehq.com/@simonw/search-for-faucets-with-cli...
https://observablehq.com/@simonw/openai-clip-in-a-browser
Those are both from https://simonwillison.net/2023/Oct/23/embeddings/
https://observablehq.com/@simonw/gpt4all-models provides a readable version of JSON file on GitHub
https://observablehq.com/@simonw/blog-to-newsletter is the tool I used to assemble my newsletter
A killer feature of Observable notebooks for me is that they provide the shortest possible route from having an idea to having a public URL with a tool that I can bookmark and use later.
> A killer feature of Observable notebooks for me is that they provide the shortest possible route from having an idea to having a public URL with a tool that I can bookmark and use later
Thanks for sharing simon! I'm working on an Open Source Notion + Observable combination (https://www.typecell.org), where documents seamlessly mix with code, and can mix with an AI layer (e.g.: https://twitter.com/YousefED/status/1710210240929538447)
The code you write is pure Typescript (instead of sth custom like ObservableJS) which opens more paths to interoperability (aside from having a public URL). For example, I'm now working to make the code instantly exportable so you can mix it directly into existing codebases (or deploy on your own hosting / Vercel / whatever you prefer).
If you run `marimo tutorial fileformat`, that'll open a tutorial notebook that explains the fileformat in some detail.
Since I've thought about this for a long time (I've actually even made a very simplified version last year [1]), I want to contribute a few thoughts:
- cool that you have a Vscode extension, but I was a little disappointed that it opens a full browser view instead of using the existing, good Notebook interface of Vscode. (I get you want to show the whole Frontend- But I'd love to be able to run the Reactive Kernel within the full Vscode ecosystem.. Included Github Copilot is cool, but that's not all)
- As other comments said, if you want to go for reproducibility, the part about Package Management is very important. And it's also mostly solved, with Poetry etc...
- If you want to go for easy deployment of the NB code to Production, another very cool feature would be to extract (as a script) all the code needed to produce a given cell of output! This should be very easy since you already have the DAG.. It actually even existed at some point in VSCode Python extension, then they removed it
Again, great job
[1] https://github.com/micoloth/vscode-reactive-jupyter
nbgather used static slicing to get all the code necessary to reconstruct some cell. I actually worked with Andrew Head (original nbgather author) and Shreya Shankar to implement something similar in ipyflow (but with dynamic slicing and a not-as-nice interface): https://github.com/ipyflow/ipyflow?tab=readme-ov-file#state-...
I have no doubt something like this will make its way into marimo's roadmap at some point :)
1. Can you describe your interactive widget story? I see that you integrated altair, and there is some custom written react code around it [0] [1]. I'd be interested in porting my table widget to your platform at some point.
2. How much, if any does this depend on the jupyter ecosystem?
3. How does this interact with the jupyter ecosystem?
[0] https://github.com/marimo-team/marimo/blob/b52faf3caf9aa73f4... [1] https://github.com/marimo-team/marimo/blob/b52faf3caf9aa73f4...
2. marimo was built from scratch, it doesn't depend on Jupyter or IPython at all.
3. marimo doesn't interact with the Jupyter ecosystem. We have brainstormed the possibility of a compatibility layer that allows Jupyter widgets to be used as marimo plugins, but right now that's just an idea.
What would be the best way to use it locally in a minimal, self-contained install?
Can you talk about it in more detail?
Can I tell who the user is so I can have multiple annotators?
Can I use gold data to determine which annotators aren't paying attention?
Where do I learn more about how to build this kind of tool?
Overall, kudos, I signed up for the waitlist.