What if we wrote widgets and wikitext using JSX and React?

What if tiddlers were JSX render functions, and widgets were react components? The widget render tree is basically the same idea as a React render tree. TiddlyWiki markup is basically JSX (with a few annoying quirks). We could probably even use something like react-jsx-parser, which is built on acorn and appears significantly smaller than the full 3MB that something like ESBuild takes.

Variables could easily use be implemented using react context. The tiddler store could be enhanced with RxJS and components could subscribe to individual tiddler changes or react dynamically to wiki events. Message bubbling can also be implemented using context.

Widgets would receive a set of functions which they would use to tie into the various services. Things like message bubbling and tiddler subscriptions would be implemented in core and then exposed via an API of sorts using React hooks.

Nearly every concept which the render tree currently has can be directly translated to React. Even filters and lists work just fine. The children of the $List widget take their item and index from the state variables. The react version of this would just render children inside a variable context.

Many things would need to be memo-ized, but that can be abstracted away inside custom hooks and memo-ed components.

The only thing I’m not sure how to add is Typescript. Without typescript, a lot of this feels pointless. However there are some ways which JSDoc comments can be strategically and effectively used to accomplish this.

What do you see this accomplishing? Tiddlywiki has a longer history than React, and is dependency-free. At the moment, we don’t need to bend our notions to someone else’s, or change to meet an ever-updating API. What would be the advantage?

2 Likes

React itself is very stable and has a huge ecosystem around it, far bigger than ours. So they’re at least as concerned about not breaking the entire internet as we are, if not more. The biggest advantage I see would be the ability to make a lot more use of existing projects and frameworks.

  • We could use existing themes and frameworks that are built on React.

  • It would smooth the difference between widgets and macros, as a macro would just be a react component without any state.

  • It would also bridge the gap between developers and tinkerers, giving developers an existing framework which they understand, while still allowing tinkerers the ability to do what they always do.

  • It would put TiddlyWiki into the context of an incredibly large and diverse ecosystem. Any react developer could instantly understand what TiddlyWiki is about. We wouldn’t have to figure out exactly how the widget tree works, for instance, because that would be handled by React, and we already understand React.

  • TiddlyWiki could also be converted to Just Another React Framework and used in existing React projects with very little effort. The widget documentation as well could be formatted to match typical React framework documentation.

I thought the whole idea of wiki-text was to keep us at arms-length from JS and underlying technologies?

3 Likes

I think it was just to make it easy for anyone to understand and change what was going on. On the plus side, the existing wikitext format could still be supported, since the parser tree gets converted to a widget tree under the hood anyway. I don’t actually think it would change much for the most part.

Even simpler, the parse tree could be converted to JSX, making the JSX format an intermediate step.

The biggest advantage would be to smooth the transition for developers without making things harder for power users.

Please, please understand that React and Typescript are terrible.

1 Like

What size of JavaScript projects do you normally work on? Most of my projects are between 20 and 50 fairly large files (~1000 lines each) and keeping all the types straight is a nightmare in JavaScript.

I tend to work in project with closer to 1000 - 2000 files, but most of them between 25 and 100 lines each, and no more than a few with 250+ lines. But I generally work in a functional programming style. (I’m the founder of the FP library Ramda.) With FP, I work more with a few consistent fundamental types rather than a lot of custom ones. I find it extremely rare to have type errors.

I’ve tried most of the major UI frameworks. In fact I led a team here at GigantiCorp in creating our own framework, back when Backbone and Knockout—not robust enough for our needs—were the leading contenders, a framework that was in production from 2011 - 2024. I don’t like any of the frameworks, even the one I created. So maybe I’m just a curmudgeon.

I mostly avoid Typescript. When I work in Haskell, getting the types right is often the end of the work; once you have them correct, the logic of the program is blindingly obvious. When I work in Typescript, I simply feel as though all I do with it is fight the compiler, with no benefit at the end. It doesn’t help clear up any of the logic; it just adds verbosity. It may have changed since I last looked, but AFAIK, TS still does not support higher-kinded types; that’s a deal-breaker for the sort of code I prefer to write.

I don’t avoid React. Most front-end apps at my company are now in React. But I cannot say I love it.

I’ve done a lot of TW in the past few years, but only edged around the core. I’ve got to admit that I’ve not spent any time at all thinking about the widget tree. Perhaps one day I’ll get there, but so much TW work can be managed without thinking about it at all.

I have written a plugin that enables me to write widgets in preact directly in the browser. I use preact signals to 2-way bind to tiddlers. I have a simple syntax based on tiddlywiki, eg

<$pwidget $app="simple.mjs" 
          $tids=`[[comment|commentTid]] [[#pcounter1|cntTid1]] [[#pcounter2|cntTid2]] ` title={{titleTid}} 
          errorMessage="Error in app"
/>

where $tids has preact signal comment bound to tiddler commentTid etc, and simple.mjs is a preact component.

The plugin is called ‘unchane’ and can be seen in these applications:

It is a reasonable size at 54K

2 Likes

Obsidian is not opensourced, I don’t like it and won’t use it to store my personal info. But it uses TS + React, and has a much larger plugin developer community, and has 100x + users than TiddlyWiki.

And what’s the problem when Tiddlywiki is in a niche market: Android app, the TidGi-Mobile app v0.7.7 - #10 by linonetwo

TS for plugin dev: GitHub - tiddly-gittly/Modern.TiddlyDev: Modern TiddlyWiki Developing Environment

React based widget example: GitHub - tiddly-gittly/tiddlywiki-whiteboard: Tiny little drawing app in TW, using tldraw. Providing diagram widget and whiteboard view.

I know old Tiddlywiki users won’t use them. But new users will accept them. So it is important to get incremented user, instead of persuading old user groups.

As @Arlen22 notes, there are striking similarities between React and TW5’s widget system. When React came to my attention (probably in 2014) that part of TiddlyWiki 5 was already completed, and I saw the design of React as a validation of where I had ended up with the architecture TiddlyWiki (the architecture of TW5 evolved from a lot of trial and error)

I don’t see much benefit for users from re-architecting TiddlyWiki to adopt React. There is an argument that it would make it easier for JavaScript developers to get up to speed but I think that is best addressed by the sort of adaptor that @btheado and @linonetwo mention. I would be very happy for us to have one as an official product.

1 Like

Yes, when I got to know more about how to write tiddlywiki widgets, I felt more and more familiar with it. React is just a further replication of tiddlywiki.

1 Like