DesignDesigning for incremental adoptionWritten by Emil Sjölander on Thu Apr 23 2020

Ever wanted to try out a new framework, tool, or library and stopped halfway through because you realized that it would be way too much work to migrate your existing project onto this new shiny thing? This is a common problem with a lot of new tools, especially in the no-code space. The first step in any onboarding process is typically to start a new project, but this doesn't work for most people who work on large existing projects.

With Visly, we took a different route: a core pillar of our product philosophy is that any project, small or large, should be able to get up and running with Visly in less than five minutes. Adopting Visly should also not require the developer to delete, re-write, or re-think any part of their app or development process. Over time, we hope Visly can help you replace a ton of styling code and incorporate designers into the development process. But these things should never be pre-requisites to using Visly. So while most no-code design tools assume you are starting a new project, we actually assume the opposite!

Before starting Visly, I was working on building UI frameworks at Facebook, some of which you may have even used like React Native, Yoga, or Litho. Core to the success of these frameworks was their adoptability across a wide range of projects, from small hobby projects to apps used by billions of people. But what's more interesting about my time working on these frameworks is not their success, but instead what I learned from seeing countless other attempts at frameworks and tools that didn't go anywhere. All of those projects had a common built-in assumption: that they'd be adopted as part of a re-write. The problem with this is that while many of us dream and talk about re-writes, they're actually pretty rare because of their inherent cost. As a result, having a fresh slate as a default assumption, however inadvertent that may be, is not really the best strategy here. For this reason, we chose to make sure that Visly wouldn't require anyone to re-write their codebase or start a green field project to use it (and we happen to think this a pretty solid strategy for increasing adoption of a tool or framework ūüėé).

This approach necessitates building for incremental adoption, which requires a lot of hard work. I wanted to show you some of the things which we have done with Visly to ensure it can be smoothly integrated into your existing codebase.

Just another import

Instead of inventing a new module system, building a custom bundler, or creating some other way to get components from Visly into your project, we chose to go with an old but proven route. You just import a Visly component like any other component (because they are ūü§ę). You don't need to configure your build system with any custom plugins or anything like that; if you are using create-react-app or a similar setup, Visly will work out of the box. A huge benefit here is that it works with all existing systems: Typescript works out of the box, tree shaking works perfectly, VSCode's jump to definition. Everything just works (#obvisly).

This works because under the hood, all Visly does is write code to your file system. The file system acts as a universal API to almost every other tool. A lot of design decisions in Visly were made to work within these constraints to ensure compatibility. For example, we chose to make Visly a desktop app so that it could have this kind of access to the file system.

Use with existing libraries

Today we use Visly to build and style a lot of the components within Visly itself. Before we could do this, though, we relied heavily on styled-components. As a result, we made sure that the components we build in Visly work within that system, since otherwise it would be hard for us to incrementally move over to Visly components. We spent a lot of time ensuring Visly components work with your existing CSS as well as any CSS-in-JS library you may use using, whether it's styled-components, glamor, or emotion.

It's not only styling libraries that work well with Visly components: you can use them wherever you'd use any other React component. This means Visly works with any React library, whether you want to wrap Visly components in higher-order components or pass them as render props. How did we do this? Well it's actually pretty easy: all we have to do is make sure your Visly components get a style and className prop which is correctly applied in the generated code.

Hot reload just like code

Let's be honest, hot-reload is so important that I would not want to build an app without it and I would not use a tool if it stopped me from using hot-reload. It's such a huge productivity gain that we knew we could not release Visly if it broke the hot-reload workflow in any way. So we made sure that every change in Visly hot-reloads your app just as quickly as a code change would.

The great thing about designing Visly to automatically take advantage of the existing ecosystem is that we can access new exciting features without needing to do anything. We don't even need you to update your app. As soon as fast-refresh and other improvements to hot-reloading land in tools such as Next.js and create-react-app, we instantly benefit from them as well.

Works with source control

We could have made Visly an online service with a web app and its own versioning system which you would need to somehow integrate into your existing workflow. This is what most apps do these days. We wanted to give you a better experience. Something where you could start using it right away without needing to figure out how to collaborate with co-workers, where to store API keys or any of that.

Visly works with your file system and the version control system you are already using. Because it works with git, it also works with GitHub, Bitbucket, and most other tools. While there are a ton of interesting problems to solve to make this experience seamless (and that would probably make for a great article on its own), one that I think is important to mention is merge conflicts. Historically, merging changes in files auto-created by tools has always been a huge pain, and we felt this acutely early on using Visly. Our way of fixing this was to build a merge tool into Visly that deals with this for you: you just run visly resolve (or @vislybot resolve with our GitHub integration) and the headache's solved.

In conclusion

All decisions are a matter of weighing trade offs. One trade off I don't think is valued highly enough is compatibility with existing systems. It can feel great, and be a lot easier, to make a clean break from any existing processes. But this can greatly increase the barrier for people to use a library, tool, or framework - a huge downside. At Visly, we have chosen to emphasize and value compatibility. For us this means sacrificing realtime / live collaboration as well as a browser-accessible UI, as both these features, while very valuable, are not compatible with the current workflows for software development. (We do have plans to bring both these features back into the product in various ways, albeit with some limitations. Stay tuned for the future ūüéČ)

If you have any questions about Visly or comments on the article, please reach out over email or Twitter. If you want to give Visly a try, please request access here.