
Start With What You Don't Know
TL;DR: When starting a product, I try to identify the things we know we don't know and investigate those first. On one project, our first version wasn't an application. It was a Jupyter Notebook. It contained just enough data processing and design to prove what the product could become. Once we understood that, we moved to the next unknown. A prototype is finished when you're confident that you can solve the problem it was built to investigate. Everything beyond that is wasted time.
Years ago, I worked on a new product in the geospatial industry.
The idea was ambitious.
We wanted to build a two-sided marketplace for geospatial data and processing algorithms.
Customers could buy different types of satellite imagery at different resolutions or request new data for specific coordinates.
But getting the data was only one part of the idea.
Customers should also be able to process it.
Algorithm providers could offer existing processing capabilities, while customers could eventually bring their own algorithms as Docker images. Those processing steps could then be connected into pipelines, with the output of one step becoming the input of another.
It sounded like a product.
At the beginning, though, we had very little idea how to actually build it.
We started with a Jupyter Notebook
The project was very demo-driven.
Every two weeks, we had to show stakeholders how the idea was developing.
We also worked with several co-creation partners who helped us understand what people might actually do with a platform like this.
One example involved analyzing imagery along railway tracks and identifying sections where vegetation indicated that tree cutting would likely be required soon.
Use cases like that made the potential of the idea tangible.
But we still needed something people could actually see and interact with.
A data scientist on the project knew that we could demonstrate surprisingly much of the idea with a Jupyter Notebook.
So that's what we built.
The prototype allowed someone to enter coordinates and a time range.
It loaded imagery for that area.
An object-detection algorithm processed the data.
The resulting image could then show annotations around the objects that had been detected.
That was essentially it.
There was no marketplace.
There was no complete application.
There was no production architecture.
There was just enough of the core idea to demonstrate what this product could eventually do.
But it didn't look like a typical prototype
I was working on the frontend, so I did something that might sound unnecessary for a prototype.
I designed it.
Not like a finished product, but enough that the notebook started to communicate what the eventual web application could feel like.
That wasn't polish for the sake of polish.
It was part of what we needed to learn.
One of the questions wasn't only:
Can the technology work?
It was also:
Can people see a product in this?
Our stakeholders weren't evaluating a Python experiment.
They were evaluating a potential business.
They needed to understand how geospatial data, algorithms and an interface could eventually become one product.
So visual design mattered.
Authentication didn't.
A production-ready frontend didn't.
A complete marketplace didn't.
A sophisticated deployment setup didn't.
Those things wouldn't have helped us answer the question we were asking.
A prototype doesn't have to be ugly
I think prototypes are sometimes misunderstood as deliberately bad versions of products.
Quick code.
Ugly interface.
Everything thrown together.
That's not how I think about them.
A prototype should contain everything required to answer the question you're investigating.
And nothing that doesn't help answer it.
Sometimes that means a rough command-line script.
Sometimes it means a clickable Figma prototype.
Sometimes it means real backend infrastructure with almost no frontend.
And sometimes it means putting custom design around a Jupyter Notebook because part of what you're trying to understand is whether people can imagine a product around the technology.
The question defines the prototype.
Not the other way around.
After three or four weeks, we knew more
That first prototype took roughly three to four weeks.
By the end, the stakeholders behind the project had something tangible enough to understand the vision.
More importantly, we had learned enough to move forward.
We didn't know how the final platform would work yet.
We didn't have the production architecture.
We hadn't solved all of the engineering problems.
But that wasn't the purpose of the prototype.
We had reduced one important uncertainty.
And once we did that, another one became much more obvious.
The next unknown was much harder
A notebook could demonstrate an algorithm processing some data.
A platform needed to make that generic.
Customers weren't supposed to use one algorithm we had hardcoded into the application.
They needed to be able to build processing workflows.
That meant running different Docker containers in a defined order.
Each processing step had inputs.
Each had outputs.
Those outputs needed to be usable as inputs for subsequent steps.
The system needed to know which things could be connected.
And eventually the frontend needed to expose this through a visual editor where users could construct their own processing workflows.
This was not a problem our usual web application architecture answered.
And for a while, we weren't entirely sure how we were going to solve it.
So we prototyped again
We didn't start by designing the entire production architecture around our best guess.
Two backend engineers investigated the problem.
They built prototypes.
They experimented with running and orchestrating containers.
They explored how inputs and outputs could be defined and enforced.
Different approaches were evaluated.
Eventually, Argo Workflows emerged as the solution that worked for what we needed.
At that point, something important had changed.
We weren't guessing anymore.
We had knowledge.
There were still thousands of engineering decisions ahead of us, of course.
But one of the fundamental questions behind the product had moved from:
How could this possibly work?
to:
We know this can work. Now let's build it properly.
That is exactly what I want from a prototype.
Start with the knowledge you know you don't have
This became a principle I've used ever since.
When starting something new, there are usually plenty of things I already know how to build.
Authentication isn't particularly scary.
Neither is a CRUD API.
I know how to structure a frontend.
I know how to create a database.
I know how to build forms, tables, settings pages and navigation.
Those things still require work.
But they don't contain much uncertainty.
If there is one part of the product where everyone in the room says:
We're not actually sure whether this is going to work.
That's where I want to start.
Build the knowledge you know you don't have.
The known parts can wait.
The easy parts create a dangerous feeling of progress
There is something very tempting about starting with the things we understand.
You can create the repository.
Set up CI.
Build authentication.
Create the database schema.
Implement the first few screens.
Add a navigation.
After two weeks, there are lots of commits.
There might even be something that looks like a product.
Everyone feels productive.
Meanwhile, the one thing that determines whether the entire idea works remains unanswered.
That's not the kind of progress I want to optimize for.
I'd rather spend three weeks with an ugly repository and one weird Jupyter Notebook if those three weeks turn the largest unknown in the product into something we understand.
Lines of code are cheap compared to discovering three months later that the central idea doesn't work.
Not all uncertainty is technical
The same principle isn't limited to engineering.
Sometimes the thing you don't know is whether users understand an interaction.
Prototype it in Figma.
Sometimes you don't know whether people will pay for something.
Test the proposition before building it.
Sometimes you don't understand the domain.
Get domain experts into a room and model it.
Sometimes you don't know whether a third-party system can support an integration that's fundamental to your product.
Build that integration first.
Sometimes you don't know whether a processing pipeline built from arbitrary containers is feasible.
Don't build the marketplace around it.
Run the containers.
The tool depends on the uncertainty.
A prototype is not version one
This distinction is important.
A prototype doesn't need to evolve into the production implementation.
It might.
But that shouldn't be the goal.
The goal is knowledge.
Trying to make prototype code reusable can easily lead to spending time on things that don't contribute to learning.
Should this be properly abstracted?
Do we have enough tests?
Does it follow our production architecture?
Is the folder structure correct?
Can this support the next five use cases?
Those are perfectly reasonable questions when building a product.
They can be completely irrelevant when building an experiment.
If the prototype proves that an approach works and you throw every line of it away the next morning, it can still have been enormously valuable.
It did its job.
Know when to stop
This also means a prototype needs an exit condition.
Otherwise prototyping can become another form of endless engineering.
For me, that condition is fairly simple:
A prototype is finished when you're confident that you can solve the core problem it was built to investigate.
Not when the code is clean.
Not when it has complete test coverage.
Not when every edge case works.
Not when somebody could deploy it to production.
Once the uncertainty is sufficiently reduced, stop.
Take what you learned.
Then decide how the real thing should be built.
Everything beyond that is usually wasted time.
Find the next unknown
The interesting thing about building new products is that removing one uncertainty often reveals another.
Our first prototype helped demonstrate that there was a product worth pursuing.
Then the processing architecture became the important unknown.
Once that worked, we could focus on turning it into an actual platform.
This creates a very different way of thinking about early product development.
Instead of asking:
What should we build first?
I prefer asking:
What do we need to learn first?
Then build the smallest thing capable of teaching you that.
Learn.
Throw it away if necessary.
Find the next unknown.
Repeat.
Eventually, there are fewer unknowns and more things you simply need to execute.
That's a much better moment to start building the product.
This is how I build Vuesion
These aren't just ideas I write about. They're principles I've been building into Vuesion for more than eight years.