# Introducing Shaku - a family of tools that help write tech articles

# My frustration on Markdown

Since 2 years ago, I have been writing about how React works internally in the series of React Internals Deep Dive, yet I constanly feel frustrated about the writing experience.

My posts are written in Markdown, which is a quite good choice except that:

- Markdown generated posts lack interactivity
- it is hard to explain code snippet, especially for longer ones

For technical posts, interactivity is very important to provide readers with good learning experience. Looking at great posts from nan.fyi or web.dev, we can see that great posts should have following components.

- interactive demo
- code editor
- typography components
- quizzes
- diagrams
- …

And there doesn’t seem to be existing solutions to my needs, so I decided to create some by myself.

# Introducing Shaku - a family of tools that help write tech articles

釈-

elucidate, explain

I’m building a bunch of modules based on my writing experience from jser.dev, it might be a UI component, markdown parser plugin or anything that might be useful, all will be put under the umbrella of “Shaku”

## shaku-code-annotate - annotate code snippets in markdown

Let’s take a look the first tool from Shaku - shaku-code-annotate, to understand what I mean by “help write tech articles”.

Suppose I need to explain code about binary search authored by others, so I add following snippet to markdown.

markdown

```js/*** search the index of target, or the position to insert* @param {number[]} arr* @param {number} target*/function binarySearch(arr, target) {let i = 0let j = arr.lengthwhile (i <= j) {// choose the center every time and move cursor// to one of the halvesconst mid = Math.floor((i + j) / 2)if (arr[mid] === target) {return mid} else if (arr[mid] < target) {i = mid + 1} else {j = mid - 1}}return i}```

markdown

```js/*** search the index of target, or the position to insert* @param {number[]} arr* @param {number} target*/function binarySearch(arr, target) {let i = 0let j = arr.lengthwhile (i <= j) {// choose the center every time and move cursor// to one of the halvesconst mid = Math.floor((i + j) / 2)if (arr[mid] === target) {return mid} else if (arr[mid] < target) {i = mid + 1} else {j = mid - 1}}return i}```

Problem is that I want to emphasize that the `while`

condition is `i <= j`

, not `i < j`

,
because me myself often get it wrong.

I could add some more comments to the line of code, but the original code already has 2 lines of comments, which makes it hard to tell the context if I just put them there, like below.

js

function binarySearch(arr, target) {let i = 0let j = arr.lengthwhile (i <= j) {// ^// [attention that it is <= here, not <]// [it makes sure one more of round of comparison when i and j meets]// choose the center every time and move cursor// to one of the halvesconst mid = Math.floor((i + j) / 2)if (arr[mid] === target) {return mid} else if (arr[mid] < target) {i = mid + 1} else {j = mid - 1}}return i}

js

function binarySearch(arr, target) {let i = 0let j = arr.lengthwhile (i <= j) {// ^// [attention that it is <= here, not <]// [it makes sure one more of round of comparison when i and j meets]// choose the center every time and move cursor// to one of the halvesconst mid = Math.floor((i + j) / 2)if (arr[mid] === target) {return mid} else if (arr[mid] < target) {i = mid + 1} else {j = mid - 1}}return i}

The core issue is that **I want to annotate the code in the context of the post, not the context of the code**,
which cannot be addressed with just a simple code snippet.

Now with shaku-code-annotate, we are able to annotate code in a new context, out of the code itself.

To start, we need to first add the right plugin. This website is built with astro, it uses remark
to parse Markdown, so I added remark-shaku-code-annotate.
We only need to add `annotate`

to the code block meta to kick it off

diff

-```js+```js annotatefunction binarySearch(arr, target) {let i = 0let j = arr.length...}```

diff

-```js+```js annotatefunction binarySearch(arr, target) {let i = 0let j = arr.length...}```

For the binary search example, we are able to see it rendered like this.

function binarySearch(arr, target) {let i = 0let j = arr.lengthwhile (i <= j) {attention that it is <= here, not <

it makes sure one more of round of comparison when i and j meets

// choose the center every time and move cursor// to one of the halvesconst mid = Math.floor((i + j) / 2)if (arr[mid] === target) {return mid} else if (arr[mid] < target) {i = mid + 1} else {j = mid - 1}}return i}

function binarySearch(arr, target) {let i = 0let j = arr.lengthwhile (i <= j) {attention that it is <= here, not <

it makes sure one more of round of comparison when i and j meets

// choose the center every time and move cursor// to one of the halvesconst mid = Math.floor((i + j) / 2)if (arr[mid] === target) {return mid} else if (arr[mid] < target) {i = mid + 1} else {j = mid - 1}}return i}

Isn’t it cool? Below is an example showing a lot more options, including underlines and highlights.

const blog = "https://jser.dev"JSer.dev is the homepage for JSer.

Check it out!

// This is normal comments from source code.const blog = "https://jser.dev"~~~~~~~~JSer.dev is the homepage for JSer.

Check it out!

const blog = "jser.dev"--------Check it out!

const blog = "jser.dev"........Check it out!

const blog = "jser.dev"........const blog = "jser.dev"--------const blog = "jser.dev"~~~~~~~~function useSomeEffect({blog}) {~~~~~~~~~~~~~useEffect(() => {// do some stuffreturn () => {location.href = 'https://jser.dev'}This cleanup function is super important

}, [blog])}

const blog = "https://jser.dev"JSer.dev is the homepage for JSer.

Check it out!

// This is normal comments from source code.const blog = "https://jser.dev"~~~~~~~~JSer.dev is the homepage for JSer.

Check it out!

const blog = "jser.dev"--------Check it out!

const blog = "jser.dev"........Check it out!

const blog = "jser.dev"........const blog = "jser.dev"--------const blog = "jser.dev"~~~~~~~~function useSomeEffect({blog}) {~~~~~~~~~~~~~useEffect(() => {// do some stuffreturn () => {location.href = 'https://jser.dev'}This cleanup function is super important

}, [blog])}

visit Shaku Playground to see the source code.

This is just the first tool from the box, stay tuned and follow shaku on github.