Bike 2.0 Proof of "some" Life!

It says Bike 2.0 in the heading, but don’t get too excited!

This demo is rough and limited.

I’m throwing this out now for a few reasons:

  1. I do think it’s ready for a few eyes
  2. I’ll be away from the computer for this upcoming school vacation week
  3. It’s been too long with me working on own, I want to get into a cycle of post an alpha/beta, get feedback every few weeks.

You’ll need to read through all these notes to make any sense of it. Reading through the notes will give a people of what 2.0 will become, it will also give you a chance for very early feedback.

Regarding feedback, not looking for specific bugs, just general thoughts and responses to these notes and direction that I’m taking Bike 2.0. In this release I’m also looking for more details feedback on the theme and stylesheet system.

Get it running notes:

  1. Launch App
  2. Open existing document
  3. Choose Window > Themes > Demo
  4. Use Outline Indent/Unindent/Move etc commands through keyboard shortcuts
  5. Use Window > Themes > Open Themes to open the themes folder
  6. Open the Demo.biketheme in VS Code.
  7. Edit the index.js stylesheet file and when you save the outline theme should update

Generally this demo should be able to open/save existing Bike files, and that’s about it.

The default demo theme is just a demo with as many switches flipped to the on position as possible. It’s not the proposed look and feel for Bike 2.0.

Some basic things work, but a lot of other basic things do not work. For just a start, there are no visible handles, focus buttons don’t work, most higher level UI’s (like text checking, etc) are not implemented. Scroll animations are a bit broken.

Big picture notes:

The reason for Bike 2.0 is that I ran into problems when I started adding themes and filtering to the Bike 1.0 codebase.

At a very high level the problem was that Bike 1.0 stores your outline as a flat list of lines, and then derives the outline structure from those lines. This made implementing themes and filtering difficult, because they are both very tree structure oriented.

I tried the smart approach of incrementally moving Bike’s design from flat list model to tree model, but each time I tried I would give up after a few days in a sea of code errors.

Instead Bike 2.0 is a new start, rebuilding everything from scratch. This is wonderful fun, but it’s a very slow process. Along the way I’ve had some design thoughts…


I want to make Bike 2.0 simpler. And in particular I want it to work more like a traditional outliner and less like a text editor.

For example in Bike 1.0 there are two modes, text mode and outline mode. In text mode if you move a line the lines children don’t travel with it, while in outline mode they do.

In Bike 2.0 commands always work on the outline structure. So when you Outline > Move up you’ll always get the same behavior. Child rows move with parent.

This is simpler because now there’s one way of working with the outline. It’s also simpler because the old way had two ways to work with the outline, and then it had exceptions to those rules. For example in text mode rows would travel with a parent if the parent was collapsed.

This simplification is a big break from 1.0. And not quite set in stone, but pretty close.

Another change towards traditional outliner and away from text editor is the selection model. In Bike 1.0 you could select from any character to any character in the outline… like a text editor.

In Bike 2.0 selection you select characters in a row, but once you extend the selection to another row the you start selecting at the row level. (Use left or right arrow) key (or escape) to go back to character level editing.

Note that the current transitions between row level selection and text selection will be improved. I think it can be a pretty seamless interaction when fully implemented.


I’ve spent a lot of time trying to get animations right in 2.0. In 1.0 the animations are good, but there is a lot of smoke and mirrors. It looks like an outline structure, but what you see on screen is really just a flat list of rows. There is no hierarchy.

In Bike 2.0 the outline is represented as a true hierarchy of layers that mirror the outline structure. So a parent row really does contain it’s child rows. This means it’s now possible to draw branch container boundaries, and generally provide many more styling opportunities for themes.

The focus in/out animations are also much improved. In Bike 1.0 they were more of a transition from one set of rows to another. It looked like you were zooming into a branch, but that was smoke and mirrors.

In Bike 2.0 the view is always displaying the entire outline. Focusing doesn’t recreate a new set of rows, instead it’s more like moving a camera to focus into a specific part of the outline.

When you focus in notice that you can still see (dimmed) the higher level (not focused) rows of your outline. This behavior is controlled by the stylesheet. You could completely hide those rows or make them more visible through the stylesheet.

This new approach for focus makes for cleaner animations. I think it can also make focus in/out a little less confusing, since (depending on theme) you can always have a hint of where you are.

One more thing to try with focus in/out is that now if you focus into a folded branch it will expand automatically. And then automatically collapse when you focus back out. Finally, and it feels quite nice with the animations I think.

A big part of the trick with all of the above features was to keep Bike efficient while supporting these features. It can still open much bigger files than most other outliners. :slight_smile:

Last, some parts of animation system are still very rough. For example I haven’t implemented final caret movement and typing animations yet.


Themes are a big part of this demo, but the basics are covered above. Also each .biketheme has a index.js file which defines the theme’s stylesheet. And then a types.ts file which defines the API and theme documentation. Make sure to check out the types.ts file!

The themes support is also just preliminary. For example right now you can’t theme any of the UI controls. But if you are the type of person who wants to make themes please poke around and let me know what kinds of things you would like to do that you can’t in the current setup.

Starting Bike 2.0 feedback cycle today. Let me know what you think.



Ohlala! Gotta give this a spin. :slightly_smiling_face:

I’m really excited for this.

I haven’t played around with it too much to offer any super-valuable insights into the technical stuff, but as an end user, here are my 2 cents:

  1. Animations feel supersmooth, but also slower than 1.0. In general, Bike V1 feels much snappier with scrolling and handling larger outlines. I know it’s a work in progress.

  2. Modes

IMO the ability to select partial text from multiple rows was one of Bike’s standout features for me as a long-form writer, precisely because it felt like a text editor rather than a classic block-based app. I feel it would be a shame to lose this feature because it does make a difference for those of us that write and edit more than a few lines of text. It makes moving from drafting to final draft much easier.

I think this is just timing settings. Generally I have animations set to slower speeds right now because it makes spotting animation bugs easier.

I think final decision on this won’t be made until the rest of the app is really polished, but can you give me an example of where you would want to do that?

For me, I found that I missed ability to move caret through multiple paragraphs, but it was more something that I did for something to do… a continuous motion. My final edits nearly always happened within a single paragraph, or on paragraph boundaries. Now that I am a bit used to it I don’t miss it.

For anyone playing with themes here’s a basic theme that turns all the extras off for a view closer to Bike 1.0: (5.2 KB)

Sure. Anytime I work on anything else than a first draft, I’m frequently shuffling things around, a lot of times it ends up being multiple paragraphs, or parts of them combined with others: Character dialogue, pacing etc, but mostly it has to do with cutting stuff out rather than rearranging. Other times it’s combining ideas split between paragraphs. It gets annoying when I’m constrained to whole blocks when selecting. One wrong move and your whole selection is gone :sweat_smile:

1 Like

Fascinating. I’ve never even considered using Bike for long-form text like this! :smiling_face:

I didn’t use any outliners before Bike. But discovering it made me realise that when using Markdown editors, a very large portion of my time was spent making lists - as that’s just the way I like to structure my thoughts. And then obviously a dedicated outliner is way better at this!

Now, I’m not saying “you’re using it wrong!”, because I totally get the urge to use Bike for everything - as it’s just that good. :stuck_out_tongue: And I absolutely think you should voice the concerns related to your workflows. But I guess it’s a bit like the podcasters who edit their shows in Logic: It does work, and perhaps even well - but as it’s not the main use case for the app, there might be changes that prioritise the main use case above niche ones.

(You didn’t ask - but lately I’ve been using what I’d call “The Bike of Markdown editors” :sunglasses: : Paper. It’s too expensive, but the free version is very generous. And it’s a small developer also needing support, so buying it is a good thing as well. :slightly_smiling_face: It’s more minimalistic than long-form mainstays like (the also great) Ulysses and iA Writer. So if your do end up being disrupted by Bike 2.0, I’d take a look in that direction! I use Bike alongside Markdown editors, so it’s not either-or. :blush:)

I do actually want to make Bike work for this use case, long form writing.

In my mind an outliner is a more powerful text editor. It should work for writing long documents. It will have a different feel than more standard writing tools, but it should work. And in some ways it should work better I think.

In current form it’s missing some somewhat major things. I think for example a sidebar index for navigation would really help for long documents. Also some publishing mechanism to process an outline into a sharable document. All those are down the road post 2.0.

Lots to explore here – I really like the power and flexibility of this stylesheet design.

A minor quirk for testers is that the version 2.0 demo, sharing a bundle ID with Bike 1.0, turns out – at least on this system, if you install the demo to /Applications – to become the default target of any script which writes:

  • Application("Bike") in JS, or
  • tell application "Bike" in AppleScript

I think ways around it, while we’re exploring the demo, may include:

  1. testing the demo from some folder other than /Applications/, or
  2. specifying a full path to Bike 1, for example with:

Huh, that’s interesting. I can absolutely can see the possibility, though!

For instance, one thing I like about Ulysses is how easy it is to move parts around - and Bike is obviously also good at that. And I always like my text editors to support folding (like NotePlan and, ofc., FoldingText), which outliners also does.

And while Bike only support one header level (at the moment), I suppose you could indent to simulate the other levels - and that this also could work on export.

I agree that it’s a good long-term goal to have it work well for long-form writing. But in a world with lots of competition and limited dev resources I think it’s smarter to focus on the stuff that makes Bike (and outliners) unique (which I feel like you’re doing, btw!), instead of making sure it also does all the stuff Ulysses (and so many others) already do, if you know what I mean.

Now I’m absolutely an “outliner novice”, and not an “Outliner purist” who’s saying “Outliners should only do this, and not that!”. :stuck_out_tongue: But to give a concrete example, I know that handling of media (images etc.) is on your radar. And if it was to be a serious contender for long-form writing, this is obviously needed. But I don’t mind it not being at the top of the prioritiy list, because there’s already tons of apps I can use for academic writing or blog posts. And as you already have tons of great ideas for features that these apps don’t have, I’d rather see you focus on them (see, Bike 2.0! :blush:).

An arbitrary number, already defined, as you say, by indentation.

See, for example: Blog post: Scientific refereeing using Bike Outliner - Bike Outliner - Hog Bay Software Support

and particularly:

Absolute vs. relative hierarchy in document markup languages

it is the context of a node that determines what its level in the hierarchy is, not the node itself.

i.e. to be a header of level N is not a quality of the row itself – it’s a (nesting) relationship to other rows, and to the scope of the subdocument which you are considering or using.

Once Bike has flagged a row as a header, its effective level depends on:

  • where it is,
  • what sub-outline / sub-document you are extracting,
  • and what you are defining as the outermost starting level for the purposes of formatting that sub-document, for a specific use.

(and, in the Bike 2.0 stylesheet system, you will be able to define different visual styles for data-type="heading" rows at different levels of nesting).

1 Like

Here’s one way you could do that:

defineRowRule(".heading count(ancestor::*) = 2", (env, row) => {
    row.color = Color.systemGreen()

I’m just heading off now for kids spring vacation road trip (9 days). Will be checking in, but intermittently.


Cool! Does that re-contextualise as you focus in/out?

That’s very interesting, @complexpoint ! And especially this, as you say :point_down:t2:

I’m not trying to come off as a downer here! As mentioned, I want to use Bike for as much as possible. And I’m usually the guy who expects too much of software, and sometimes wants stuff to be more than the creator might want it to be, heh. :sweat_smile: And perhaps I’ve been a bit too narrow in my view of what an outliner can do, influenced by stuff like what Omni Group says about theirs.

But I’d love it if Bike was a great place for long-form writing, as well as structuring ideas, etc. - so I don’t want to come off as I’m trying to limit that!

But in that case, I’m not sure the change that takes away the possibility of marking text in different rows, without marking everything, is a good one… You know, the thing from @Gorgonzola that started it all. :wink: Because that makes it a better (traditional) outliner, but at the expense of more classical long-form writing.

Writing already works superbly in Bike. It’s what drew me to it in the first place: the fluid animation and snappy feel, typing affinity… Everything added afterward, e.g. the ability to hide basically the whole UI when writing was icing on top. But longform editing is a different beast and this is precisely why I think block editing is a step backward :smiley: But I think we may disagree on a political level: I don’t share the opinion that using Bike is hard :rofl:, and I loved having two distinct options of working the outline.

Thanks, I know about Paper, but I can’t find a use case for it. I already own iA Writer and Ulysses, and I really need a document library, I hate working with files. Bike is an exception here because it’s so good :slight_smile:

Hah, yeah - I feel exactly the same! So much so, that I made a large shortcut, to make it easier to use Bike as my document library (both creating files from it, and linking other files to it). :grin:

My thought process was the following:

  • I like Bike so much, that I want to use it even though I have to deal with files.
  • But then I have to do some stuff to make dealing with files better for me.
  • And then maybe I should have my main Markdown editor also be files based, so I’m all the way into files again? (Hence Paper.)

I’ve also adapted a ruby script that automatically tags my Markdown and Bike documents with native Finder tags if I write something on top of my documents. :blush:

CleanShot 2024-04-12 at 23.18.27@2x

1 Like

I am interested to see how this develops as well. I downloaded the 2.0 beta but almost immediately gave up on it, as it’s too unfinished for me personally to mess around with at this time, since I use Bike for work stuff. Maybe if I were on vacation! :slight_smile:

I just wanted to vociferously echo the plea to keep the current (what I would think of as “normal”) behavior of selecting text. I would like to preserve the ability to select whatever random little old fragment of text I want, just as I do in any other editor. What the relationship between this and the ultimate decision about modes is, I am not savvy enough to predict or weigh in on. I love almost all of Bike’s current idiosyncrasies (with the major exception of those infernal squiggly marks every time I make curly quotes), but I’m afraid if we deviate too far from established text-editor behaviors, it might start getting too confusing and ultimately frustrating to be used full time without extra mental overhead.

I don’t think so :slight_smile:

Possibly a slight misunderstanding ?

( not a beta - just a demo of a couple of things - particularly of a flexible approach to defining display styles )

Right, sorry for the imprecise vocab. In any case, I just wanted to voice concern about text selection’s behavior possibly changing.

I wonder if I am missing something here ?

When I select text, it tends either to be:

  1. within a row – part, but not all, of the row text. Moving a word or clause for example, OR
  2. One or more whole rows. (Moving some rows to a new position, for example)

What I don’t find myself doing is selecting across row boundaries …

I can’t immediately imagine, for example, selecting the lower half of one row, and the top half of the next row.

Can anyone explain a use case in which they feel that that might arise in their rough drafting or restructuring ?

Wouldn’t it just be a symptom of the document’s segmentation failing to match its meaning ? A case of needing a simple row split keystroke ( :leftwards_arrow_with_hook: ) , or perhaps row join ( ⌫ ), in other words, rather than an exotic selection ?

Have users of OmniOutliner, for example, complained that such half and half selections (across row boundaries) are frustrated ?

(I don’t think I’ve ever noticed any discussion of that kind …)

Yes. Shortening a point made across two paragraphs into a single paragraph for brevity and moving from abstraction to concreteness. Or taking one piece of narrative/dialogue and placing it somewhere else.