About floro

I'm not a software engineer

What is floro?

Floro is a version control system for things that are better represented through visual diffing than line-number oriented diffing. In web and mobile development these are things like SVG icons, rich text content, translations, as well as color palettes and themes. At its core, floro allows developers to create applications for visual content types that can be diffed meaningfully.

In addition to versioning, floro allows content plugins to share data in a manner similar to how files in an OS interoperate. For example, our SVG Icon plugin uses the data from our theming plugin to automatically create dark mode versions of each icon. This makes floro an excellent tool for centralizing static content that can be consumed across multiple code repositories.

Floro ultimately enables non-technical team members to contribute to a code-base in a type-safe manner that is respectful of engineering processes. Floro lets content contributors test out offline-changes with your production website or app as their canvas for testing. You can let a designer directly add icons to your code-base or test out a new color theme, or let a copy-editor test a new tag-line or fix a typo. They can then open up merge requests and make live content changes to production that you can guarantee won't break your application, all without having to redeploy a new build of your app.

Where can I see the solutions floro offers?

We'd recommend watching our demo video to get a good sense of how floro works and what floro offers. You can also download the app and test one of our many demo applications that you can find in our development documentation. For a comprehensive overview of the system and details and features of each plugin, please visit our general documentation.

How is floro different from a headless cms?

The short answer is level of structure. Traditionally, CMSs targeted marketing functions so marketers could easily churn out blog posts and static content without needing to get engineering involved. Due to the nature of blogging, this also made most CMS use-cases highly html-centric in nature. Even in the world of headless CMS, CMSs largely exist to aid with marketing. A CMS shines when you have a redundant data format and are targeting web as a single platform. The cracks start to show when it comes to the non-linear data content-types that commonly occur in application development.

Floro excels at managing content that necessitate type-safety or needs to work cross-platform. It's better to think of floro as a replacement for something like an i18n library than a CMS, however, floro benefits from many of the features that have made headless CMS so useful in recent years, such as content-previews, and real time updates. Due to the highly structured nature of floro, floro is able to do some things safely that would be risky to do with a headless CMS, such as updating complex string content in production. Floro is great for handling content consumed by dynamic applications, while a CMS is great for handling content consumed by a static website or a blog.

To give the longer answer, we have to first delineate the two common types of headless CMS, Api based and Git based. An API based CMS has a database and is usually consumed by a Rest API or a GraphQL API. Git based CMS do not have a database and usually persist your content in some form of markdown that is usually checked into the same source control repository as your application.

API based
CMS have the major benefit of allowing anyone on your team to update content in real time. They're usually user friendly and are great for when you have team members who would rather chew glass than learn how to fix a git merge conflict manually. The downside to an API based CMS is that they can introduce a lot of complexity to things like CI/CD. More often than not, API based CMS lack proper versioning support and tend to be a nightmare for optimizing for things like SSR.

Git based
CMS have significantly less infrastructure complexity due to the fact that they don't require a separate service from your application. You can also do more complex things with a Git based CMS since they are coupled to your code base and are inherently versioned -- meaning a compiler can catch content changes that might break your application if you were using an API based system. The two main drawbacks to Git based CMS is that they don't tend to scale very well when you introduce non-technical members to your team. They also require full-app redeployments to make any content change. Again, this works well when your application deployment process takes less than 5-minutes but begins to become tedious when your build pipeline gets longer and you have to rerun your entire deployment pipeline to fix a typo.

Perhaps the most ubiquitous CMS amongst engineers is the No CMS. If you don't have any requirement to allow non-engineers to manage content and you don't need to localize your application or deal with dynamic static assets, this is a great option. The performance literally cannot be beat! What often happens is an application starts off this way and then i18n comes up as a requirement. Eventually the application moves its strings to json files, po files, or strings.xml files. Maybe if you're really fancy, you might have some form of static analysis that extracts your strings from your code to a KV store for translation. Perhaps you upload your translation files to a translation service or use a service like Phrase, Localize or Lokalise for managing translations. This is fine but you've inadvertently introduced both a Git based CMS and a API based CMS to your codebase without gaining any of the real benefits of either.

While many teams have figured out that you can mix a headless CMS with an i18n solution to get real time string updates, the problem remains that unless you know the argument input types of the strings you're interpolating, you are at risk of breaking your application. Floro does not have this problem. For example if you delete a phrase used in production or change the method signature of a phrase and push your change to production, the string will not be deleted or updated in production. This means you can essentially break production without actually breaking production. The great thing about this is it allows you to get all the benefits of an API based CMS and all the benefits of Git based CMS, while gaining the additional benefit of type-safe content. Additionally, floro is runtime agnostic. Phrases in floro can be rendered in a react app as html, a mobile application as native rich text, or in a CLI application as plain text. This makes floro especially useful for content that needs to be consumed across various runtimes without having to break all of your strings into isolated plain text components.

When shouldn't you use floro?

Don't use floro for static websites or blogs. It's a little ironic that we are writing this section of our site with floro (we're in the market for a good headless CMS if you know of one). Just as you can bend a CMS to work for KV style string content, you can certainly bend floro to work as a CMS. But it's way too much friction to use floro to create blog articles. We're only using floro for our static site because we have to battle test this thing.

There are two caveats to this. If for some reason you are thinking of writing a rich text heavy mobile application, floro supports native rich text rendering (no html). You might find that the editing and development experiences are better with floro than one of the many existing headless CMS systems that proclaim to support mobile (what they mean is you can inject html or plain text into your mobile app).

The second caveat is if you have a one-off article that weaves a lot of javascript-intensive content into the article. In that case floro might be a better option over a headless CMS.

Floro is great for complex dynamic apps that need things like optimized SSR rendering. If you have a marketing team, do not make them write blog posts in floro. Get a CMS! It's not the right tool for the job!

Why does offline-first matter for content management?

While we believe there is a lot of beauty and value in the local-first software movement, such as privacy, data ownership, and data portability, those aren't the reasons why we choose offline-first. We also think it would be intellectually dishonest to say there is no lock-in with floro. We're an upstream dependency to your code, of course there is lock-in. Although we have taken considerable steps to make sure if we shutdown or get acquired, you aren't entirely screwed. For one, we are truly Open Source (MIT Licensed for everything, no Fauxpen Source nonsense). You are free to self-host and you can transfer your floro repository histories between hosts with relative ease (though we still have a little work to do here).

Ideology aside, we didn't choose to be offline-first for any of the reasons above, we choose to be offline-first because it was easier to implement. Early on we realized we needed an event-sourced architecture for floro to work. If you have an event sourced client application, default offline is dramatically easier to implement than building something like a remote version of git that has to support sessions. Theoretically we think you could make an online version of something like floro but we shudder at the server bill and the performance costs.

It's also a much better developer experience to work with offline content. There's a reason 20 years into the existence of cloud platforms, software developers still work primarily offline-first. Wouldn't it be cool if other people could have that workflow too?

How many people is floro?

As of writing this, we're a company of two people. One engineer and one designer. We previously operated a company that was part of the YCombinator W21 batch, called Cheqout. We built an application for people to order by QR code from restaurants right before the pandemic began. We had very fortunate timing during the pandemic but ultimately did not see a market need for QR codes after the pandemic subsided. Floro is what we ended up pivoting to. It was a tool that we felt was desperately needed during our experience working on Cheqout.

While we understand it can be quite risky to take a bet on technology from such a small team, it should also be reassuring. We don't have a high burn, our main way of generating revenue is consulting around floro and installing floro. If you hire us for consulting, you get the attention of literally our entire company.

Why on earth did you choose electron?

We needed something that could work cross platform and start a node server in the background. We have too many complicated port/socket requirements to work as a PWA and we really liked the idea of having floro available in our desktop docks. As cool as Tauri is, we didn't want to take the risk of working with a new universal desktop app. There were still some questions about Tauri's stability for things like auto-update when we started the project. Perhaps we will switch to it in the future.

What user data do you collect and what tracking does floro do?

We don't collect very much information. Our entire database schema is public so you can take a look yourself. When you login with an OAuth method we collect the name and email associated with the third party provider. We use this to implement our authentication logic and assist with first time account creation.

Other than that, we track page views with Fathom Analytics, which does not use third party cookie tracking. Page views are also anonymized to us.

We do not collect or store any information about branches, commits or any work in progress state that has not been explicitly pushed to our remote servers. All repository commits and state are stored in our S3 bucket and are only accessible via signed URLs.

Other than that, we do use Sentry for crash reporting, however, even crash reports are anonymized to us. Our plan for now is to rely upon the community to help file bug reports and assist us with replicating issues.

Do you support enterprise?

If you're willing to take on a two person startup then we absolutely support enterprise. We are happy to work with your security team to make sure floro can satisfy the requirements your company may have. We can support on-premise hosting and work with your security team to get their requirements around SSO. You can safely trial floro with our public hosted solution, if your company uses SSO for email then you pretty much get SSO already (floro does not have password logins). Our data retention is more or less infinite since it's an offline-first application. We also have a very robust role-based access control system with comprehensive key management support. We can also provide maintenance and training.

How beta is floro?

A little beta but definitely production ready. We haven't had a mission critical failure in about 4 months (we've dog-fooded and QA'd extensively). To us mission critical bugs are things where we corrupted the local version history or lost work in progress. There's definitely tiny bugs littered throughout the application but nothing that makes it unusable or laggy to the point that we would prefer an alternative method of managing or editing content.

If you are working on a large repository, you may run into some memory leaks where the application crashes after the JS-heap is exceeded. Though annoying, you just have to restart the application, it's not too big of a deal.

We wouldn't launch if we didn't think we were safe for production use. You should play around with a repository and demo project yourself to be your own judge though.

Does floro scale?

You could easily scale a repository to 10k-20k KV pairs and never run into an issue. For point of reference, Airbnb (which is a huge application) was about 25K strings when I worked there. If you try to make a 100 page blog, with 1,500 word articles, it's going to be a bit rough... seriously, use a CMS.

The advice we give for scaling floro is the advice given for scaling git. Break your repositories apart when they get too large. It might take a little extra work to adapt your code-base to partitioned content repositories but it's completely doable and wouldn't be that hard to do if you already have floro installed in your code-base.

Commit-wise, you could scale floro to 100k commits on a normal tech-company laptop. You'd have a very long time to wait while cloning repositories but it would work fine.

How do I create a plugin or generator?

If you're really gung-ho on building a plugin, we will give you some of our beta documentation. Reach out to us on Discord and we'll do a personal lesson on how the SDK works.

The code and the command line tools all already exist, but there are some things that we would really like to feel are permanently spec'd that we still feel a little bit iffy about. If you're willing to accept those risks, then you are more then welcome to build your own plugin. We actually have open governance as far as publishing plugins goes, so you could push a plugin to floro right now if you could decipher the plugin API yourself.

We promise we will release documentation soon.

Why the name floro?

Originally the project started off as a way to remap the colors of your icons from light mode to dark mode. Fluorophores are molecules that absorb lower energy light and re-emit the light at longer wavelengths. We thought it was a nice analogy for dark mode since glow in the dark things are fluorescent.

Why the duck?

The duck is a vestige from another pivot. We ended up ditching the idea but really liked the duck. We also knew we were going to do something around type safety and structural equivalence so the duck seemed extremely fitting (see duck typing).