# Sota Misaki — Full Content
> A high school student and an active engineer.
Location: Japan, Nagoya
Updated: September 25, 2026
Website: https://sotamisaki.com
---
# Bio
My work primarily revolves around software development and system design.
I engage in various technological fields, including web application development, CLI tools, infrastructure building, and experimental AI-related projects.
In my personal projects, I emphasize not only validating new technologies but also shaping them into practical, usable tools. I am particularly interested in developer productivity, information organization, and automation.
You can explore my [skills](/skills) and [snapshots](/snapshots), read the [blog](/blog), or [get in touch](/contact) — I'm always open to conversations, collaborations, and new ideas.
---
# Skills
URL: https://sotamisaki.com/skills
- **TypeScript** (Language): Primary language across 100+ projects.
- **JavaScript** (Language): ES2020+ features, async/await, and browser APIs.
- **HTML / CSS** (Language): Semantic markup and modern CSS including custom properties.
- **Go** (Language): CLI tools and lightweight HTTP servers.
- **PHP** (Language): RSS feed generation for school news and blog sites.
- **Python** (Language): Scripting and tooling for automation tasks.
- **React** (Frontend): Hooks, context, and component composition with TypeScript.
- **Astro** (Frontend): Islands architecture, content collections, SSG/SSR.
- **Next.js** (Frontend): App Router, server components, and static export.
- **Remix** (Frontend): Full-stack web framework with nested routing and loaders.
- **Tailwind CSS** (Frontend): Utility-first styling across nearly all projects.
- **Preact** (Frontend): Lightweight React alternative for performance-focused apps.
- **Vite** (Frontend): Build tooling for React and Preact apps.
- **Hono** (Backend): Lightweight web framework for Cloudflare Workers and Pages.
- **Cloudflare Workers / Pages** (Backend): Edge deployments, serverless APIs, and static site hosting.
- **Chrome Extension** (Tool): Content scripts, service workers, and extension APIs.
- **Discord.js** (Tool): Built 10+ bots including translation, logging, and ticketing.
- **MCP** (Tool): Model Context Protocol servers for iCloud Mail and school portal.
- **PostCSS** (Tool): Built plugins for class name obfuscation and custom property obfuscation.
- **Google Apps Script** (Tool): Automation scripts for Gmail forwarding and LINE-Discord integration.
---
# Snapshots
URL: https://sotamisaki.com/snapshots
- **River festival** (July 2026 — Mie): Festival participants in blue happi coats wading through a river in Mie
- **Evening light** (July 2026 — VISON, Mie): Golden sunset light cast through a window onto a hotel room wall at VISON
- **Flags & hills** (July 2026 — Mie): Flags flying against green hills and blue sky in Mie
- **Wagtail** (July 2026 — Mie): A white wagtail standing in green grass
- **Ise udon** (July 2026 — Mie): A bowl of thick Ise udon topped with chopped green onions
- **Souvenir birds** (July 2026 — Mie): Two glass bird figurines on a windowsill at sunset
---
# Cinema
URL: https://sotamisaki.com/data/cinema.json
Confirmed theatrical watch history.
- **ルックバック** / Look Back (September 25, 2026) — Eirin 125426, TMDb 1591675, IMDb tt39094605, Dolby Cinema, Midland Square Cinema
- **超かぐや姫!** / Chou Kaguya-hime! (September 24, 2026) — Eirin 125240, TMDb 1575337, IMDb tt38872297, Dolby Atmos, Midland Square Cinema
- **バックルームズ** / The Backrooms (September 4, 2026) — Eirin 61196, TMDb 1083381, IMDb tt26657236, Dolby Cinema, Midland Square Cinema, subtitled
- **スパイダーマン:ブランド・ニュー・デイ** / Spider-Man: Brand New Day (August 6, 2026) — Eirin 60813, TMDb 969681, IMDb tt22084616, 4DX 3D
- **トイ・ストーリー5** / Toy Story 5 (July 15, 2026) — Eirin 60711, TMDb 1084244, IMDb tt29355505, Standard, TOHO Cinemas
- **コナン ハイウェイの堕天使** / Detective Conan: The Fallen Angel of the Highway (May 10, 2026) — Eirin 125316, TMDb 1545621, IMDb tt39123115, Dolby Cinema, Midland Square Cinema
- **ザ・スーパーマリオギャラクシー・ムービー** / The Super Mario Galaxy Movie (April 27, 2026) — Eirin 60881, TMDb 1226863, IMDb tt28650488, ULTRA 4DX Japanese version
- **シン・エヴァンゲリオン劇場版** / Evangelion: 3.0+1.0 Thrice Upon a Time (February 26, 2026) — Eirin 121619, TMDb 283566, IMDb tt2458948, EIDR 10.5240/3E5C-6A40-B273-C37F-C51D-L, Dolby Cinema, Midland Square Cinema
- **ズートピア2** / Zootopia 2 (December 15, 2025) — Eirin 60317, TMDb 1084242, IMDb tt26443597, ISAN 0000-0007-A47A-0000-M-0000-0000-8, EIDR 10.5240/1901-BF97-C569-CD4B-0612-J, Dolby Cinema, Midland Square Cinema
- **ヱヴァンゲリヲン新劇場版:序** / Evangelion: 1.0 You Are (Not) Alone (November 20, 2025) — Eirin S-2169, TMDb 15137, IMDb tt0923811, ISAN 0000-0002-59FD-0000-Y-0000-0000-9, EIDR 10.5240/2BE6-8C44-606F-03B7-5445-U, Iki "Shikou" Sound, Midland Square Cinema
- **映画 虹ヶ咲学園スクールアイドル同好会 完結編 第2章** / Love Live! Nijigasaki High School Idol Club Movie: Final Chapter Part 2 (November 20, 2025) — Eirin 125279, TMDb 1154800, IMDb tt36454732, Dolby Cinema, Midland Square Cinema
- **ジュラシック・ワールド/復活の大地** / Jurassic World Rebirth (September 25, 2025) — Eirin 60459, TMDb 1234821, IMDb tt31036941, ISAN 0000-0007-85CE-0000-A-0000-0000-7, EIDR 10.5240/94D1-8E30-8267-089D-E989-P, Osaka Station Cinema
---
# Contact
URL: https://sotamisaki.com/contact
- Email: contact@sotamisaki.com
- https://github.com/sotamisaki
- https://qiita.com/sotamisaki
- https://note.com/sotamisaki
- https://x.com/sotamisaki
- https://www.npmjs.com/~sotamisaki
- https://mastodon.social/@sotamisaki
- https://www.youtube.com/@sotamisaki
- https://www.facebook.com/sotamisaki
- https://bsky.app/profile/sotamisaki.com
- https://www.linkedin.com/in/sotamisaki/
- https://www.wantedly.com/id/sotamisaki
---
# Experience
URL: https://sotamisaki.com/experience
- **Magnet Festival 2026 Live Studio MC** (April 2026): Served as the MC for the Magnet Festival 2026 live studio.
- **ZEN Study Web App Contest 2025 Winter Award** (February 2026): Received the Best Award at the ZEN Study Web App Contest.
- **ZEN Study Web Page Contest 2025 Summer Award** (October 2025): Received the Best Award at the ZEN Study Web Page Contest.
- **Part-time Worker at Amatec Inc.** (September 2025): Started working as a part-time employee at Amatec Inc.
- **Digital Committee Representative** (August 2025): Served as the Digital Committee Representative in the student council.
- **ZEN Study Web App Contest 2024 Winter Award** (March 2025): Received the Special Viewer's Award at the ZEN Study Web App Contest.
- **ZEN Study Web Page Contest 2024 Summer Award** (October 2024): Received the Award of Excellence at the ZEN Study Web Page Contest.
- **S High School Admission** (April 2024): Enrolled in S High School (April 2024 – March 2027).
- **Open Data Hackathon Participation** (March 2024): Participated in the Tokyo Open Data Hackathon and presented a project.
- **Yadokarikun Development Member** (March 2024): Worked as a developer of the Yadokarikun estimation support tool.
- **Tokyo OSS Party 2024** (March 2024): Participated in Tokyo OSS Party and received a community problem-solving award.
- **Joined Gisoukurabu (Tech Creative Club)** (January 2024): Joined the Gisoukurabu community to participate in open source development.
- **Robot Proficiency Test (MINDSTORMS EV3) Grade 3** (October 2019): Passed Grade 3 of the Robot Proficiency Test for LEGO MINDSTORMS Education EV3.
- **Robot Proficiency Test (WeDo 2.0) Grade 3** (June 2018): Passed Grade 3 of the Robot Proficiency Test for LEGO WeDo 2.0.
- **Born** (December 2008): Born on December 15, 2008.
---
# Blog Posts
URL: https://sotamisaki.com/blog
## Publishing Myself as Open Data for AI
URL: https://sotamisaki.com/blog/open-data-for-ai
Published: September 24, 2026
Summary: An experiment in hosting machine-readable personal data so AI systems can find me — and get the facts right — without scraping HTML.
AI systems already talk about people. Sometimes correctly, sometimes with confident nonsense: wrong school, wrong location, a project that never existed. I don't have a grand product goal here. I just want to make it easier for models and tools to find me, and to pull accurate information when they do.
So I turned my site into a small personal open-data experiment.
## What I published
Alongside the usual pages, this site now hosts structured JSON about me:
- [`/data`](/data) — human-readable overview
- [`/data/me.json`](/data/me.json) — complete package (start here)
- [`/data/index.json`](/data/index.json) — catalog of available datasets
- split files for profile, experience, skills, posts, and projects
The data is licensed under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/). CORS is open (`Access-Control-Allow-Origin: *`), so browsers and tooling can fetch it directly.
This sits next to the existing LLM-oriented exports:
- [`/llms.txt`](/llms.txt) — site index for language models
- [`/llms-full.txt`](/llms-full.txt) — fuller text dump
- `.md` endpoints on blog and project pages
Different formats for different consumers. JSON for structured retrieval. Plain text for prompt-style ingestion. Markdown when you want the original writing.
## Why open data, not just a nicer About page
HTML is for people. Scraping it for identity facts is brittle: class names change, copy gets rewritten for layout, and secondary details drown in chrome.
Open data flips that:
1. **Discoverability** — a stable URL advertises “here is canonical data about this person”
2. **Correctness** — one source of truth for name, location, experience, and links
3. **Reuse** — agents, RAG pipelines, directories, or simple `curl` scripts can consume it without a custom scraper
I already maintain this content as TypeScript modules for the site. The open-data endpoints mostly serialize what the pages already render. No second biography to drift out of sync.
## What “success” looks like for an experiment
I'm not optimizing for a metric. The interesting questions are softer:
- Do assistants cite these URLs when asked about me?
- Does structured JSON reduce mix-ups with similarly named people?
- Is a personal dataset catalog useful enough that I'll keep updating it?
If the answer to any of those is yes, the experiment paid for itself. If not, I still have cleaner machine-readable exports than before.
## How to use it
Fetch the package:
```bash
curl -s https://sotamisaki.com/data/me.json | jq '.profile.name, .profile.location'
```
Or browse the catalog:
```bash
curl -s https://sotamisaki.com/data/index.json | jq '.datasets[].url'
```
If you're building something that needs a short, reliable snapshot of who I am — name variants, role, experience timeline, skills, posts, projects — prefer `/data/me.json` over guessing from search snippets.
## Closing note
This isn't a claim that every person should become an API. It's a small bet: if AI is going to remember and describe us anyway, we might as well publish something intentional for it to find.
The datasets live at [`/data`](/data). I'll keep them in sync with the rest of the site as things change.
---
## Running the Gemini-1 Grand Prix
URL: https://sotamisaki.com/blog/gemini-1-grand-prix
Published: September 18, 2026
Summary: How we responded to a collapsing submission rate during the Gemini-1 Grand Prix — and how the final round ended with 2,822 submissions.
import Gemini1SubmissionsChart from "../../components/Gemini1SubmissionsChart.astro"
From July 2025 to February 2026, the N High Group student council and Digital Committee ran **Gemini-1 Grand Prix**, a recurring contest where students used Google's Gemini to explore how much the way you prompt — and the way you think about a problem — can change the result.
I wrote the [official N High Group blog post](https://nnn.ed.jp/blog/u4ruhk5rl/) about the project as well.
That article covers what the contest was and what students created. This post is the other side of the story: operating it, watching submissions fall, trying to understand why, and changing the system while it was still running.
## The problem we kept hearing
Generative AI was already familiar to most students. Knowing that Gemini existed, however, was very different from knowing what to do with it.
We repeatedly heard variations of the same two problems:
- "I've heard about generative AI, but I don't know how to use it for school."
- "I've tried it, but I can't get anything useful out of it."
There was another problem too.
Using AI could easily become the goal in itself: write a vague prompt, accept a vague response, and call the process finished. That was not the kind of AI use we wanted to encourage.
So instead of running another workshop that ended with "try Gemini sometime," we built something students could enter repeatedly.
Participants designed their own prompts, submitted the resulting output, and explained what they were trying to achieve. The process behind the output mattered just as much as the output itself.
## Six rounds, 3,411 submissions
We ran six rounds between July 2025 and February 2026.
Students could submit more than once because iteration was part of the point. We did not want the contest to reward only one polished attempt; we wanted students to experiment, improve their prompts, and try Gemini in different situations.
Submissions were evaluated across four areas:
- prompt design
- output quality
- originality of the use case
- how logically the approach matched the problem
By the end of the project, we had received **3,411 submissions**.
But the total alone hides the most interesting part of the story.
The July–August round started with **336 submissions**.
Then participation dropped sharply:
- September: **21**
- October: **26**
- November–December: **127**
- January: **79**
The final February round received **2,822 submissions**.
The early rounds were primarily operated by the third-term student council. From November onward, the fourth-term student council took over operations, and I was involved as the Digital Committee representative.
For us, the challenge was no longer simply "run an AI contest."
It was: **why are students not submitting, and what can we change about the system?**
## The real problem wasn't Gemini
When we took over, the hardest problem was not Gemini itself, and it was not the judging rubric.
It was participation.
A contest can have a good concept, good prizes, and good judging criteria, but none of that matters very much if entering it feels inconvenient or unnecessary.
I started treating the low submission count as an operational problem and looking for friction in the participation flow.
Several things stood out.
### 1. Public posting created unnecessary friction
Originally, submitting an entry involved running a Slack workflow and posting both the prompt and the generated result into a channel.
That meant participation was also publication.
For some students, that was fine. For others, it meant showing unfinished ideas, experimental prompts, or work they simply did not want to broadcast to a large school Slack workspace.
Those are two different decisions:
1. I want to enter the contest.
2. I want everyone to see what I submitted.
We had effectively bundled them together.
So we separated them.
Posting a use case publicly remained possible, but publishing it to the channel was no longer required in order to participate.
It was a small rule change, but it reflected a broader principle I came away with: **the minimum action required to participate should actually be the minimum action required to participate.**
Anything else is friction.
### 2. Make repeat submissions matter
The contest included judged awards, but we also wanted repeated experimentation to have value.
For the lottery component, we introduced a weighting coefficient based on the number of submissions.
Every **10 submissions** increased the lottery weighting coefficient by **10%**.
For example:
- 10 submissions had an effective weight of **11**
- 20 submissions had an effective weight of **24**
The intention was not to make the first entry less valuable. It was to give students a concrete reason to keep experimenting after their first submission.
"Submit again" works much better when another submission represents visible progress rather than simply more work.
### 3. Make the leaderboard feel reachable
We also changed how we talked about low participation.
Instead of hiding weak submission numbers behind generic announcements, we used the situation itself as part of the message.
If relatively few submissions had been made, then the leaderboard was still reachable. That was useful information for someone deciding whether entering was worth their time.
We also contacted the current **top 10 participants** directly, told them where they currently stood, reminded them that the ranking could still change, and encouraged them to keep submitting — whether to pursue the highest submission count or to improve their lottery weighting.
The goal was to make the state of the contest visible.
A leaderboard only motivates people when they can understand where they are relative to everyone else.
### 4. Separate operations from participation
Another issue was where we were running the contest.
A large part of the operation lived inside the main school Slack workspace. That made operational conversations easy to bury among ordinary school activity and blurred the line between the people running the contest and the people participating in it.
We connected the student council Slack workspace and the school workspace using **Slack Connect**.
That let us keep more of the operational side within the environment used by the student council while still connecting the project to the space where students were already active.
Technically, it was an infrastructure change.
For me, though, the bigger improvement was organizational: it became easier to separate **running the event** from **participating in the event**.
## Then February happened
February ended with **2,822 submissions**.
That is roughly 83% of all 3,411 submissions made across the six rounds.
It is tempting to look at that graph and credit one change.
I don't think the data supports doing that.
We changed several things around the same period: the participation flow, privacy expectations, incentives, outreach, and parts of the operational structure. We did not run a controlled experiment, so I cannot tell you that any single change caused the February spike.
What I can say is that we stopped treating participation as something that would happen automatically.
We actively worked on the reasons someone might decide not to submit.
Some of those reasons were about friction. Some were about incentives. Some were simply about whether students remembered the contest existed and felt that entering again was worthwhile.
The graph changed dramatically after that work.
That does not prove causation, but it made one lesson very clear to me: **participation itself has to be designed.**
## What I took away
The hardest part of Gemini-1 Grand Prix turned out not to be prompt engineering.
It was product and community design.
If someone has never seriously used Gemini before, the first interaction has to feel approachable.
If someone has already entered once, there needs to be a reason to experiment again.
If submitting something requires making it public, you should ask whether publicity is actually necessary.
And when participation is falling, rewriting the same announcement with slightly different wording is probably not enough. You have to look at the system around the announcement.
Gemini-1 Grand Prix was also a useful reminder that an educational project can be treated like a product.
You can look for friction.
You can redesign the user flow.
You can change incentives.
You can observe what happens.
And, just as importantly, you can be careful not to claim that a correlation proves which change worked.
The contest ultimately received **3,411 submissions**, including **2,822 in the final round**. More important to me than the final number, though, was learning how much the design around an activity affects whether people actually participate in it.
The school-facing version of the project is available on the [N High Group blog](https://nnn.ed.jp/blog/u4ruhk5rl/).
If I were building something similar again, I would keep three ideas from the start: make the first contribution easy, make repeated contributions meaningful, and design for the person who is interested enough to participate but is still one small piece of friction away from giving up.
---
## Snapshots: a loose pile of photos
URL: https://sotamisaki.com/blog/snapshots-collage
Published: August 10, 2026
Summary: Added a photo collage page where you can grab overlapping prints, drag them around, and leave them where they land.
I added a new page to this site: [Snapshots](/snapshots).
It's a small collage of photos — travel, meals, and everyday scenes — stacked like prints on a desk. Grab one to bring it forward, drag it somewhere else, and it stays where you leave it.
## Why a collage
A neat grid felt too much like a gallery product page. What I wanted was something closer to how I actually look at photos: a messy pile, a bit of overlap, and the freedom to pull one into focus.
Each photo has a caption, location, and date that appear when it's in front. The layout itself is just data — position, width, rotation, and stacking order — so I can rearrange the pile without rewriting the UI.
## Interaction
The page is an Astro route with a React island for the collage. Pointer events drive the grab-and-drag behavior:
- pointer down brings a photo to the front and starts the drag
- moving updates position and a soft tilt based on both horizontal and vertical offset
- releasing commits the new pose so the photo stays put
Tilt is intentional but light. Moving right or up rotates one way; left or down the other. It makes the pile feel a little more physical without turning into a physics toy.
## Keeping it light
Dragging used to push React state every animation frame, which meant re-rendering the whole collage on every move. That was more work than the interaction needed.
Now the active photo's transform is written straight to the DOM during a drag. React only updates when you pick something up or put it down. The entrance animation is a single reveal flag with staggered CSS delays, instead of flipping one boolean per photo.
Same behavior, less churn.
## What's next
Right now the set is a handful of photos from Mie. I'll keep adding to the pile as I take more — and probably keep tweaking the coordinates until the overlap feels right.
If you want to play with it, head over to [/snapshots](/snapshots).
---
## Direct Markdown Access for Blog Posts
URL: https://sotamisaki.com/blog/markdown-direct-access
Published: April 29, 2026
Summary: Added `.md` endpoints so blog and project pages can be fetched as raw Markdown, with frontmatter included.
I added a small but useful improvement to this site: each blog post can now be accessed directly as a Markdown file by appending `.md` to its URL.
This means a single post now has two representations:
- a regular web page for reading in the browser
- a raw Markdown response for machine-friendly use
For example:
- `/blog/circle-reveal` renders the regular HTML page
- `/blog/circle-reveal.md` returns the raw Markdown source
The `.md` response includes both frontmatter and body content, so it can be reused in external tools, scripts, and feed-like integrations without scraping HTML.
## How it works (light version)
I added an API-style route at `src/pages/blog/[slug].md.ts`.
At build time, Astro reads post entries from the content collection (`getCollection("posts")`) and generates one `.md` route per slug.
When a request comes in:
1. the route finds the matched post data
2. it converts metadata into frontmatter text
3. it appends the original Markdown body
4. it returns everything with `Content-Type: text/markdown`
So instead of reverse-engineering rendered HTML, tools can consume the post in its original writing format.
## Why this is useful
Direct Markdown access is convenient for:
- personal archiving / backups
- script-based content processing
- lightweight integrations with external services
- AI ingestion (LLM context input, summarization, and embeddings/indexing pipelines)
- future tooling (for example, syncing or indexing workflows)
In addition to blog posts, the same `.md` access pattern is available for project entries.
---
## A Hidden Easter Egg: Circle to Reveal
URL: https://sotamisaki.com/blog/circle-reveal
Published: March 11, 2026
Summary: How a small interactive easter egg on the contact page works — triggered by circular cursor movement, not clicks.
If you visit the contact page and move your cursor in slow circles for a while, something will quietly appear at the bottom of the screen. It's a small interactive easter egg — a hidden "Back to home" link that reveals itself only when it senses a certain kind of motion.
## How it's triggered
Most cursor-tracking interactions measure total distance traveled. This one is different: it measures the *angular change* of your movement.
Every time your cursor moves, I compute the angle between the previous movement vector and the current one. These small turns are accumulated over time. A straight line — scrolling up and down the page, for example — produces almost no angular change, so it doesn't count. But circular, swirling motion changes direction constantly, and the angle accumulates quickly.
Once the total exceeds a threshold (about five full rotations' worth), the hidden element fades in. Stop moving for a couple of seconds and it disappears again, resetting the counter.
## The math
The angle between two vectors is computed using the cross product and dot product:
```ts
const cross = prevDx * dy - prevDy * dx
const dot = prevDx * dx + prevDy * dy
totalAngle += Math.atan2(Math.abs(cross), dot)
```
`Math.abs(cross)` means we always accumulate the magnitude of the turn, whether the cursor is going clockwise or counterclockwise. Only movement segments longer than 3px are counted, to filter out noise from tiny jittery movements.
## Why
I wanted the contact page to feel a little more alive — something that rewards curiosity without demanding attention. Most visitors will never find it, and that's fine. It's the kind of detail that makes a site feel like it was made by a person.
---
# Projects
URL: https://sotamisaki.com/projects
## Twilic — Weaving Repeated JSON into One Wire
URL: https://sotamisaki.com/projects/twilic
Tech: Rust, TypeScript, MessagePack, WebAssembly, N-API
Summary: A compact binary format for structured data that stays schema-less like MessagePack while shrinking repeated shapes, keys, and strings in batches and sessions.
Website: https://github.com/twilic/twilic
[Twilic](https://github.com/twilic/twilic) is a documentation-first specification and multi-language implementation for a compact binary format aimed at structured data. The name comes from Old English _twilic_, the root of modern _twill_: repeated threads woven into one fabric—same idea for repeated object shapes, keys, and strings in a single wire representation.
I am building Twilic because JSON and MessagePack are easy for one-off objects, but **the same schema sent hundreds of times** still pays for field names and repeated strings on every row. Protobuf fixes that with a fixed schema; Twilic targets the middle ground—**schema-less to start**, then automatic interning and optional bound profiles when you know the shape.
## What it does
- **Self-describing encode/decode** without a upfront schema, like MessagePack
- **Learned compression** via `shape_def`, `key_ref`, and `str_ref` when structure repeats (v2 wire in [SPEC.md](https://github.com/twilic/twilic/blob/main/SPEC.md))
- **Bound profile** (`encodeWithSchema`) to omit field names when a schema is known
- **Batch** (row/column) and **session patch** in the same format family—send deltas instead of full JSON every tick
Reference implementations live in the [twilic monorepo](https://github.com/twilic/twilic) under [`runtimes/`](https://github.com/twilic/twilic/tree/main/runtimes)—including [Rust](https://github.com/twilic/twilic/tree/main/runtimes/rust), [JavaScript](https://github.com/twilic/twilic/tree/main/runtimes/javascript) ([@twilic/core](https://www.npmjs.com/package/@twilic/core), N-API + WASM), [Go](https://github.com/twilic/twilic/tree/main/runtimes/go), and [Zig](https://github.com/twilic/twilic/tree/main/runtimes/zig). [Hono middleware](https://github.com/twilic/hono) is available for `Content-Type`-aware bodies.
## Benchmark
Sizes below use the same fixtures as [twilic/benchmark](https://github.com/twilic/benchmark) (local `@twilic/core` via N-API on Node 24). Throughput is in the same order of magnitude as MessagePack for encode/decode; the main win is **wire size on repeated data**.
| Payload | Twilic | MessagePack | CBOR | BSON | vs MessagePack |
| ----------------------- | ------: | ----------: | -------: | -------: | ----------------: |
| Single record | 140 B | 140 B | 144 B | 198 B | 0% |
| 256 homogeneous records | 5,316 B | 19,505 B | 20,633 B | 28,241 B | **72.8% smaller** |
| 256 mixed records | 9,799 B | 20,893 B | 22,204 B | 32,956 B | **53.1% smaller** |
| Session patch (first) | 89 B | 89 B | 93 B | 120 B | 0% |
On a single small object, Twilic is designed not to be worse than MessagePack. On a **256-record homogeneous batch**, encoded size drops to roughly **one quarter** of MessagePack in this harness—the case where key names and repeated strings dominate.
Reproduce locally:
```bash
git clone https://github.com/twilic/twilic.git
git clone https://github.com/twilic/benchmark.git
ln -s twilic/runtimes/javascript twilic-js
cd benchmark
pnpm install
pnpm --dir ../twilic-js build
pnpm bench -- --twilic-vs-msgpack-only
```
Compare formats in the browser via the [playground](https://github.com/twilic/playground). A longer write-up (in Japanese) is on [Zenn](https://zenn.dev/minagishl/articles/941a9f21474ce5).
## Good fit / poor fit
**Good fit:** telemetry or log batches, WebSocket events with stable shape, tabular columns (`userId`, `active`, `country`), edge-to-cloud links where bandwidth matters, teams already on MessagePack who only struggle with **array batches**.
**Poor fit (explicit non-goals):** replacing every JSON protocol, defining application semantics, or optimizing streams of tiny one-off payloads where MessagePack is already enough.
## Links
- Specification / runtimes: [github.com/twilic/twilic](https://github.com/twilic/twilic)
- Benchmark harness: [github.com/twilic/benchmark](https://github.com/twilic/benchmark)
- npm: [@twilic/core](https://www.npmjs.com/package/@twilic/core)
---
## Meijo University Athletics Association Soccer Club Website
URL: https://sotamisaki.com/projects/meijo-soccer
Tech: TypeScript, Next.js, Tailwind CSS, Cloudflare Workers, microCMS
Summary: A full redesign and rebuild of the official website for the Meijo University Athletics Association Soccer Club.
Website: https://meijosoccer.com
The official website for the Meijo University Athletics Association Soccer Club, a university soccer club based in the Tokai region. This project involved a full redesign and rebuild from scratch.
## Background
The club had an existing site, but it offered little control over markup, performance, or content structure. Several issues were making it harder to maintain and harder for visitors to find.
Key problems with the old site:
- **No semantic HTML** — missing ``, ``, and `