GitShow/honojs/hono
honojs

hono

Web framework built on Web Standards

by honojs
aws-lambdabuncloudflarecloudflare-workersdenonpmroutertypescript
Star on GitHubForkWebsitenpm

TypeScript

32.1k stars1.3k forks359 contributorsActive · 7m agoSince 2021v4.13.7MIT

Meet the team

See all 359 on GitHub →
yusukebe
yusukebe1.7k contributions
usualoma
usualoma243 contributions
EdamAme-x
EdamAme-x71 contributions
watany-dev
watany-dev53 contributions
ryuapp
ryuapp31 contributions
nakasyou
nakasyou27 contributions
metrue
metrue24 contributions
exoego
exoego21 contributions

Languages

View on GitHub →
TypeScript99.8%
JavaScript0.2%
Shell0%
HTML0%

Commit activity

Last 12 weeks · 146 commits

Full graph →

Community health

5 of 6 standards met

Community profile →
75
✓README✓License✓Contributing✓Code of Conduct○Issue Template✓PR Template

Recent PRs & issues

Active · Last activity 7m ago
See all on GitHub →
lx3133584
perf(jsx/dom): optimize matching-head child lookup during reconciliationOpenPR

Problem During JSX DOM children reconciliation in , each child in searches using and removes the matched node via . When reconciling large child lists where the order is preserved or appended, this produces $O(N^2)$ linear searches and array shift operations. Root Cause Reconciliation did not check the head of before falling back to full-array and . Fix Check if matches the current child (by string type, key+tag, or tag) and consume it directly via , reducing lookup from $O(N)$ to $O(1)$ for in-order children, while retaining and fallback for reordered or interspersed items. Related to #5306 Testing 1. Added unit test in verifying reconciliation and reordering across 100 keyed items. 2. Ran (all 24 test files pass, 1296 passed).

lx3133584 · 4m ago
adityajha77
fix(jsx): preserve self-closing void elements in cloneElementOpenPR

Summary Fixes an issue where on elements with children (such as HTML void elements `undefined[undefined]src/jsx/base.tscloneElementprops.children``ts const c = (element as JSXNode).props.children childrenToClone = Array.isArray(c) ? c : [c] When an element has no children (e.g. ), props.children is undefined. Because c was undefined, Array.isArray(c) ? c : [c] evaluated to [undefined], passing an array of length 1 containing undefined to jsx(). During SSR stringification (JSXNode.prototype.toStringToBuffer), the self-closing check emptyTags.includes(tag) && children.length === 0 failed because children.length was 1. This resulted in invalid non-self-closing HTML tags like instead of . ###Solution Check if c !== undefined before wrapping it into an array: childrenToClone = c !== undefined ? (Array.isArray(c) ? c : [c]) : [] ###Verification Added a unit test in src/jsx/base.test.tsx verifying that cloning a void element (e.g. cloneElement(, { alt: 'bar' })) preserves self-closing HTML output.

adityajha77 · 3h ago
MahathirMohammadShuvo
fix(trie-router): match a pattern node once when the path is its tokenOpenPR

returns the same handler more than once when a request path segment is literally a pattern token. stores a pattern node in under its own key as well as in , so a part equal to that key reaches the node twice — once through the literal lookup, once through the pattern loop. The copies compound per segment: route matched by the path returned the handler 8 times, and 16 times. Because the match list is the middleware chain, this runs middleware more than once: The path doesn't have to be written by hand — decodes the segment, so a request for arrives as , and as . The fix The literal branch does three jobs, and each has to stand down for the patterns the loop already covers — which is a different set for each: the push: the loop makes this itself when an array pattern matches, and never for a string one, so and a prefixed wildcard still need it here; the terminal push: the loop makes it for any pattern node whose pattern accepts the part; the descent: the loop descends through and parameters itself, but not through a prefixed wildcard, so that one still descends from here. Gating all three on one predicate does not work. In particular the push must be gated on , not on "is a pattern node" — the latter drops real matches ( + at path loses the handler, and + at likewise). The existing router suite passes under the wrong gate, so that distinction isn't covered by current tests. Behaviour changes beyond de-duplication Matches are removed where the literal lookup was the only route to a pattern node. Two shapes: 1. A constrained parameter whose regexp rejects its own key. , and reject theirs; accepts. So no longer matches the path , and neither do routes carrying anything after that node (, ). RegExpRouter and PatternRouter return nothing in all of these. 2. A parameter that is not the last segment, e.g. . Its regexp runs against the rest of the path rather than the segment, so the loop consumes the whole remainder and the segment after it is never reached. The literal lookup was the only way through, so on such a route matched only when that segment was literally — already returned nothing. PatternRouter still matches these; RegExpRouter rejects the route outright. Ordinary paths are unaffected in both: still matches , and a terminal is untouched ( still matches and ). Verification Over a corpus of one route per router, with routes and paths being every one-to-three-segment sequence of the tokens , , , , , and — 399 of each, so 159,201 combinations: results containing a repeated handler: 8,008 on , 0 here; combinations disagreeing with both and : 1,478 on , 144 here, and every one of the 144 already disagreed on — nothing new disagrees; no added matches, and no changed params on a surviving match. Tests go in the shared router suite so every configuration covers them. Five of the six run all six new cases; throws for a parameter with a trailing wildcard, so that one case carries a skip alongside its existing entries. Relationship to #5243 Independent of #5243, but the two touch the same lines of and conflict textually in (both insert a block at the same anchor). If #5243 lands first, the descent gate here needs revisiting: its pattern loop walks prefixed wildcards too, which this change deliberately leaves to the literal branch.

MahathirMohammadShuvo · 3h ago

Recent fixes

View closed PRs →
Noxtimo
fix(accepts, language): skip accept entries with quality 0 when matchingMergedPR

Fixes #5310 Description Per RFC 9110 §12.5.1 and §12.5.4, a quality value of indicates that a representation is explicitly not acceptable. The middleware already filters out entries, but in and in the middleware were matching candidates when present. This change skips entries with in both and , falling through to subsequent acceptable values or configured defaults, and adds test coverage including subtype wildcards ( and ). The author should do the following, if applicable [x] Add tests [x] Run tests [x] to format the code [ ] Add TSDoc/JSDoc to document the code

Noxtimo · 1d ago
Noxtimo
feat(context): expose preparedHeaders getter for non-allocating header inspectionMergedPR

Fixes #5313 Currently, inspecting pending headers set via requires reading , which eagerly allocates a instance and disables downstream fast paths like . This PR exposes a getter on returning , allowing non-allocating header inspection in middleware and custom wrappers.

Noxtimo · 1d ago
Structured data for AI agents

Repository: honojs/hono. Description: Web framework built on Web Standards Stars: 32100, Forks: 1287. Primary language: TypeScript. Languages: TypeScript (99.8%), JavaScript (0.2%), Shell (0%), HTML (0%). License: MIT. Homepage: https://hono.dev Topics: aws-lambda, bun, cloudflare, cloudflare-workers, deno, npm, router, typescript, web-framework. Latest release: v4.13.7 (1d ago). Open PRs: 100, open issues: 281. Last activity: 7m ago. Community health: 75%. Top contributors: yusukebe, usualoma, EdamAme-x, watany-dev, ryuapp, nakasyou, metrue, exoego, sor4chi, yasuaki640 and others.

·@ofershap

Replace github.com with gitshow.dev