![Avatar for Luke Posey](/assets/authors/luke-posey.jpg)
Luke Posey, Product Manager
Building the spreadsheet for developers means building a great developer experience.
We built Quadratic as a code-first spreadsheet from the start, to make sure code was a first-class citizen instead of feeling like a spreadsheet bolt-on. This has helped us create a solid developer experience, but there's so much more we want to do.
Below we outline the feature set we've prioritized thus far, as well as the features we're going to build over the course of this year.
Python in Quadratic, past and present
Code as a cell type
In Quadratic, code is a cell type. Cells can be data, a Formula, or code, and the cell displays the output of that code. In the example below (as code) we sum two numbers and the sum is displayed to the sheet.
The same cell, whose type is Python and contains that code, also displays the output of the code we've written.
Pyodide: Python meets WASM
We built Python directly into the spreadsheet using Pyodide, a WASM port of CPython. This allowed us to get a feature-rich web-based Python experience that runs locally on the user's machine from inside their browser. For individual users, no sending code off to a server for execution. Instead, Python executes at the speed you're used to on the computer you're used to, no spinning up and down servers for hobbyist workflows that suffer from cheap compute options.
Reading data to Python from the sheet
Once Python was live in the sheet, we started by augmenting the Python experience with some extra API calls to pass data from the sheet to Python.
# create a variable with the value of a single cell
x = cell(x1, y1)
# create a DataFrame directly from a range of spreadsheet cells, set the first row of cells as the column headers for the DataFrame
df = cells((x1, y1), (x2, y2), first_row_header=True)
Return types
From there we had to figure out how to pass data from Python to the sheet.
The best developer experience turned out to be returning the last line of code to the cell. All types of data can be passed back to the sheet. DataFrames, as the last line of code, returns the data to the sheet as a table for each corresponding value. Charts, as the last line of code, return a chart to the spreadsheet. Lists return lists. Series return series. And so on. Data is seamlessly passed back to the sheet. And, other cells can then reference that data output to do further computations.
Pandas native
Pandas is the most commonly used data analysis library in Python. We built it to be native to Quadratic; extra commands like first_row_header=True
allows better Pandas support from the sheet. Getting data in and out of DataFrames, to and from the sheet, is seamless. And we're proud to have Wes Mckinney, the creator of Pandas, as an investor in Quadratic.
Building a good editor
Building a good code editor is hard. Our editor is based on Monaco, the code editor that powers VS Code. We took Monaco and started on a journey towards building the best possible editor experience in a spreadsheet.
Some features we've recently tacked on that were less trivial than they seem:
- Return types
- Code suggestions & autocomplete
- Verbose (and correct) errors
...and many more hard problems (this section honestly requires a dedicated post to elaborate on how much work goes into making a good code editor)
A great tool for collaborating
We added real-time multiplayer editing and follow this up with Teams, features that enables Teams to have a shared space to work together on analysis.
The next step towards great collaboration is making our code editor a multiplayer experience as well.
Docs & onboarding materials
While many people may be familiar with spreadsheets, Quadratic has plenty of dedicated features that users won't find elsewhere. Experiencing a blank canvas even with some prior knowledge can be overwhelming. So it was very important we started down the journey of building great docs and onboarding materials. Over the last ~4 months we went from very little accompanying materials to:
Where we're going, the future of Quadratic
We think we've built the best developer experience in the spreadsheet, but we've got a long way to go before we are satified.
Modern spreadsheets are still not the default mode of analytics for developers - notebooks, and code-heavy tools are still capturing more users. We have many things we know we need to build to make a great developer experience, but we're also always looking for more feedback. Below are some things we know we need to build within the next 12 months. Feel free to point us towards even more features we should build: contact us.
SQL/Data connectors
One of our nearest major feature releases is SQL and data connectors. Users will be able to connect directly to their data sources and jump-start their analysis from their data. This is an obvious step-up, especially for work/enterprise use-cases, maybe less useful for hobbyist use-cases.
Cloud runners
While Pyodide is great for the individual user, we think executing user code in our cloud for enterprise customers is an obvious next step. Code execution we'll off-load to servers for the advantages users can get with varying resource levels, for free plans we'll stick with local execution so hobbyist workflows don't slow down.
Cloud runners also enable sheet APIs so you can execute sheet code on intervals or via an API call. From here users can automate reporting and many other highly sought after use-cases from user feedback.
Secrets
Writing secrets and environment variables into code in your sheet isn't ideal. Secrets are an obvious feature we'll add so Teams can work together on secrets that perhaps not everyone on the team should have access to.
Better selecting of sheet regions
At the moment, if you want to get data from cells in the sheet to a DataFrame in Python, you need to figure out which cells contain the data and then input those cell ranges in code. The next step of this evolution is drag and select, with shortcuts to auto-select large groups of data and an accompanying button press to get this data from sheet to code.
In-line formulas (= to formula, / to code)
We built Formulas as a multi-line editor by default. We've realized this wasn't the best approach much of the time and will be moving them to in-line like users are used to. We expect most analyses to happen in code, but the short Formulas work you might do to SUM() some data or perform some other quick analysis is best done with an in-line editor.
Reusable code
One of the most significant pain points in Quadratic at the moment is around code reuse. Numerous users have requested a way to create global functions they can use throughout their sheets. We're brainstorming the best way to make this possible without over-complicating the sheet.
Table-stakes spreadsheet features
We've got a long list of expected spreadsheet features like relative references, autocompleted formulas, and more that are must-haves for spreadsheet users. They fell to the back of our priorities, but we recently heard loud and clear from user feedback that we need to add some minimal spreadsheet features that we're currently missing. Sometimes, Formulas are better than code for problem-solving.
Better AI support
We added ChatGPT to our code editor, and some users love it. But we can go much further than we have. Currently, you get code recommendations based on the state of the sheet, but you have no write access. We want to add write access so when you get answers to code questions, you can accept them directly in the code. We also want to add write access to the sheet so AI can auto-generate analyses from data in your sheet. The possibilities are vast but this is an obvious direction.
More language support
Once we feel like our Python support is in a great spot, we intend to add more languages to Quadratic - JavaScript is next in the queue. Still, we want to make sure our developer experience in Python is fantastic before going down this path, despite the dev time being not so bad to get extra languages implemented.
Quadratic roadmap
We know we need to build dozens of other features, and priorities can sometimes be challenging. You can view our up-to-date roadmap on GitHub.