You are browsing as a guest. Sign up (or log in) to start making projects!

ManoX

@ManoX

Joined June 6th, 2026

  • 18Devlogs
  • 1Projects
  • 3Ships
  • 59Votes
Searching for logic in a world of syntax errors.
My Github: https://github.com/abdelkabirouadoukou
Ship

Ship #3 - X is pre-production ready

X is a full-stack React framework written natively in Bun. It has seen 90+h development and is at the point where I can hand it over to someone else and walk away.

What’s in the box

• File-based routing with SSR, SSG, ISR - pick per route
• Islands architecture for client interactivity, no more use client
• Server functions, which at build-time are rewritten to fetch wrappers
• Authentication package with credentials + OAuth2, sessions, CSRF, brute-force protection, RBAC
• Build-time environment leakage check, implemented as an AST visitor that fails the build on a secret accidental exposure
• Adapter for Vercel that generates a .vercel/output directory with static CDN and serverless SSR
• MCP server for training AI agents that write correct x applications, not hallucinating Next.js code
• Structured JSON logs, /healthz, /readyz, OpenTelemetry/Sentry hooks
• Docker builds with explicit workspace COPY gates and CVE scanning at build-time

What’s been fixed in this cycle:

• SQLite session store did not observe created_at on relogin, unlike Postgres
• The AuthGuardResult object had { ok: ‘success’, status: 401 } shape on successful auth guard resolution, has been renamed to a discriminated union type to avoid carrying stale data
• The Vercel adapter accepted comma-joined X-Forwarded-For headers that should have been rejected
• The auth package had code duplication between brute-force protection and audit logging for parsing X-Forwarded-For, consolidated into a clientIpFromRequest util
• The hero component on the landing page broke on actual mobile viewports - fixed a responsive slab assumption in the install command component
• Docs had foreign framework artifacts (use client directives, wrong loader signatures), all scrubbed

CI is properly set up now, only merged branches push changes. For every PR:

• TypeScript checks, Biome linting, tests run on Ubuntu/macOS
• Postgres migration checks, Docker builds with CVE scans
• Package audits (using a sha256-pinned manifest), load-testing with SLOs
• Vercel preview deploys, changeset validation for monorepo packages
No automatic merging - everything is watched by the repo until the CI turns green and the PR is squashed.

Repo: https://github.com/abdelkabirouadoukou/x
Docs: https://thexjs.abdelkabir.me/

  • 6 devlogs
  • 40h
  • 14.90x multiplier
  • 543 Stardust
Try project → See source code →
Open comments for this post

1h 0m 38s logged

Devlog #13

Fixed two critical auth bugs, both related to the auth package; the fixes are already in the PRs (not merged yet, waiting for CI).

sqlite session store silently overwritten created_at (#175)

Postgres store used ON CONFLICT (token) DO UPDATE, which does not update created_at column on purpose; therefore, on each re-login with the same token, the created_at would remain the same, signifying that the session was created at the same time. However, the sqlite had a different approach of INSERT OR REPLACE which replaced the whole row, including created_at. This PR changes the sqlite version to use the explicit upsert so that both databases behave the same way. Also adds a regression test that purposely creates a session, re-logins with the same token/data and checks that created_at was not changed. The postgres tests are skipped for local DATABASE_URL absent.

AuthGuardResult lied on success (#177)

AuthGuardResult was a type { ok: boolean; status: 401 | 403; reason: string }, and on success, the guard returned { ok: true, status: 401, reason: “” }, i.e., a 401 status code with an empty reason string. It was not a problem because toMiddleware always checked result.ok first, but it was a silent bug for anyone who tried to check result.status on success. Now it is properly represented as a discriminated union type { ok: true } | { ok: false; status: 401 | 403; reason: string }, and the status and reason fields are not present on success. All tests were adjusted to narrow the type with if (!result.ok) { … }, and a new test checks that TypeScript actually narrows the type.

0
0
19
Open comments for this post

5h 2m 45s logged

Devlog #12

this cycle was about mostly about closing the loop from “framework that works” to “framework someone else can actually adopt without me hovering nearby”

Most importantly, agents can now understand x

every dev I know, including senior devs, is now asking AI to write code for them. AI doesn’t know x conventions and will confidently write next.js or remix code that looks right but isn’t. So I released @thexjs/mcp - an MCP server for claude code, cursor and other agents that gives them concrete documentation for routing, loaders, server functions, env vars, and a scaffold_file tool that generates files in the right shape rather than the agent making up whatever it wants. This gets automatically added to any new project via .mcp.json / .cursor/mcp.json, and there’s also an llms.txt file on the docs for agents that just browse the site. They’re both generated from the same source so they can’t diverge.

The docs got a much needed love, not just in terms of content

I added the missing @thexjs/mcp docs page, and got it linked into the sidebar/footer/search index (it was in the code but not easy to find). I also fixed some copy that had diverged from the actual implementation, including a docs page that suggested using “use client” directives that the framework doesn’t actually support.

The landing page also got some updates

The hero section is now properly responsive (it broke on real phones, not just narrow desktops). There was a bug where the docs sidebar was supposed to be sticky but wasn’t - fixed that (turns out it was an ancestor issue, not the sticky style itself). Copy was de-genericized a bit, since it was previously very similar to other dev tool landing pages.

Some internal improvements

I fixed a bug in the vercel adapter relating to forwarded-header hostname validation, and made some improvements to the scaffolder (shadcn wasn’t being installed when tailwind was automatically enabled, doctor’s semver range checks were actually checking the ranges, etc).

I’m now using proper feature branches + PRs for everything rather than pushing to main directly. It’s more work but should avoid situations where, say, the docs get updated to disagree with the framework in confusing ways.

If you want more details on any of this, check my repo!!

0
0
27
Open comments for this post

8h 47m 31s logged

I will update this post with all fixes and fetaures i did
[Update]: Just posted my last devlog, go read that for the full details! Worked on the @thexjs/mcp server (so that AI agents won’t make up incorrect code for x), some documentation cleanup, some landing page hero/sidebar improvements, and a few adapter/scaffolder bug fixes. Repo links are included if you want to see the real code changes!

0
0
14
Open comments for this post

8h 7m 46s logged

I will update this post with all fixes and fetaures i did
[Update]: Just posted my last devlog, go read that for the full details! Worked on the @thexjs/mcp server (so that AI agents won’t make up incorrect code for x), some documentation cleanup, some landing page hero/sidebar improvements, and a few adapter/scaffolder bug fixes. Repo links are included if you want to see the real code changes!

0
0
32
Open comments for this post

13h 34m 49s logged

A loot of update i did plz check my repo to see them all
[Update]: Just posted my last devlog, go read that for the full details! Worked on the @thexjs/mcp server (so that AI agents won’t make up incorrect code for x), some documentation cleanup, some landing page hero/sidebar improvements, and a few adapter/scaffolder bug fixes. Repo links are included if you want to see the real code changes!

0
0
8
Ship

Ship #2 is finally done after 50+ hours. Shipped build-time secret leak protection, Vercel deployments, structured logging, and a 100/100 PageSpeed landing page redesign. Check the repo for all the devlogs!

  • 9 devlogs
  • 49h
  • 16.15x multiplier
  • 720 Stardust
Try project → See source code →
Open comments for this post

8h 40m 7s logged

Devlog #11

I found that browsers automatically remove tabs and newlines from a URL before checking its scheme, whereas my regex did not, and hence, I missed that javascript URLs could still bypass the sanitization and that is why they still worked. It ended up being part of releases 1.1.0 and 1.2.0.

Also, I discovered that when checking whether environment leakage exists (build command is “x build”), this check silently fails without any message if environment is indeed leaky secrets get masked properly but “x build” exits with 0 and therefore CI never discovers that a feature has quietly malfunctioned.

This time, the patches for both of these issues have been made properly and checked manually before merging.

Roadmap backlog has been taken care of after that. The items are a real end-to-end RBAC example, Redis multi-replica soak test, which would stress the multi-db system in a very large-scale environment; and a time when the security disclosure SLA is truly acted out in real life scenario not just being a paper trail.

0
0
46
Open comments for this post

5h 26m 3s logged

Development Blog #10

I spent most of my time working on the documentation backlog of adding new features. The @thexjs/auth was released a blogs ago but I still had not done the documentation for it. We did not have a page for this and some old references were no longer working in other parts of the application.

I made a page for /docs/packages/auth on the website. This page has instructions, information about the endpoints and details about CSRF. I also added links to this page from the data-layer and security pages so I do not have to repeat the information in many places.

I also started working on the testing gaps that were on the roadmap and marked as “beta” or “not tested”. This includes things like what happens when Postgres is not working problems with authorization and limits for instances using Redis.

I changed the way I work on changes. Of making all the changes in the main branch I now make a separate branch, for each change and then open a pull request. This is a way to do things so I will keep doing it this way.

0
0
22
Open comments for this post

1h 45m 31s logged

DevLog #9

I ran PageSpeed Insights on the x landing page and obtained the following results: 100 for performance, 100 for accessibility, 100 for best practices, 91 for SEO on desktop, and 96, 100, 100, and 91 on mobile.

For a page that makes no use of any framework-level image optimization or lazy-loading techniquesinstead it’s just a monochrome static page built with Bun the SEO score of 91 is likely due to the fact that I haven’t yet added the meta tags; all the other aspects are clean.

Built with x: https://github.com/abdelkabirouadoukou/x

0
0
51
Open comments for this post

7h 38m 43s logged

Devlog #8

I redesigned the landing page. It is now black and white with no color at all. I reduced the boot animation from about 5.5 seconds to 4 seconds.

CI now runs “bun run build” and a format check on every PR, not just typecheck, lint, and tests.

I rewrote most of the docs to reflect reality. There are new pages for Islands, ISR, catch-all routes, batch server-function registration, and CLI flags. I fixed several issues that had occurred, including the wrong RouteProps type, bad apiDir docs, and incorrect 404/middleware behavior. Code blocks now use a monochrome token palette that matches the new design.

I also fixed an actual bug. The rate limiter used a shared “unknown” bucket when proxy headers were missing. This meant one client’s burst could cause a 429 error for everyone else. Now it uses the correct socket IP first. I also corrected the missing content-type in the 429 response, which was causing issues with static assets in some browsers.

0
0
22
Open comments for this post

3h 10m 4s logged

Devlog #7: clean audits, fixed styling, faster boarding passes

This round was about tightening things up.

The dependency audit is finally clean with zero ignores. There are no more accepted-risk advisories in CI. Just real fixes: pinned overrides on esbuild and @hono/node-server, and moving shadcn out of production dependencies where it never belonged.

I also fixed a frustrating Vercel bug where deployed pages lost their stylesheet. It turns out existsSync doesn’t work the way you’d expect inside a serverless bundle. Now, the CSS href gets included at build time instead of being guessed at runtime.

Smaller wins: I swapped the landing page fonts to Space Grotesk, Inter, and JetBrains Mono (all self-hosted, no Google Fonts), fixed a boarding-pass demo bug where signed bit shifts were producing -6undefined seat numbers, and cleaned up lint/typecheck across the workspace.

Repo (⭐ appreciated): https://github.com/abdelkabirouadoukou/x
Website: https://thexjs.vercel.app/

0
0
17
Open comments for this post

14h 55m 19s logged

Log entry #6: on the day React’s own dispatcher attempted to become window.dispatchEvent

Today six items were shipped; one took a lot longer to track down than it should have.

The bug: clicking search crashed the site, but only in production

Click the search bar, and the command palette should appear. Instead, the deployed build produced:

Cannot read properties of undefined (reading ‘target’)

Deep inside React’s event system. Not during development. Only in production.

It has now been discovered that the island bundle is shipped as a classic rather than as a module, as a result, top-level declarations end up on the window object. In the minified bundle there was a top-level function called dispatchEvent: this was React DOM’s internal event dispatcher, having the same name as the browser’s actual dispatchEvent function, and it quietly overwritten window.dispatchEvent.

The search trigger causes a synthetic ⌘K keydown event to be sent to the window in order to activate the palette island. It was doing this by calling React’s internal dispatcher with a raw keydown event and without a nativeEvent, which caused React to fail when it tried to read .target from an object of the incorrect shape.

Solution: wrap each emitted island bundle (including the build output and the dev path) in an IIFE so that no top-level declaration now reaches the window object at all. This has been tested to ensure it works correctly.

Nested layouts were rendering inside-out

The _layout.tsx files contained within the route folders were behaving incorrectly by having the section layout wrap the root rather than the reverse. In order to correct this, the wrap order was reversed in the function renderPageWithLayout so that the root always remains the outermost element.

Hydration mismatches stopped spamming the console

Islands that have a non-deterministic initial state (mostly games) will always cause a mismatch with SSR output; although React handles the situation without any problems by re-rendering on the client side, each mismatch is still logged as a full error which could in turn spread through the event system. A no-op function was passed to the onRecoverableError handler so that these errors fail silently.

Shipped: ⌘K command palette + a konami code easter egg

The fuzzy-search palette is now its own island with React as its root, appearing through the same synthetic keydown event that brought up the bug mentioned above (as usual, dogfooding), and I’ve also included a Konami code easter egg.

Vercel adapter

The x build –adapter vercel now produces a proper .vercel/output in accordance with Vercel’s Build Output API, including the static HTML and island chunks as well as a bundled serverless render function. The route preloading and createApp have been adjusted so that the behaviour of the static and serverless versions matches that of local development. The packages/adapter-vercel have been divided into their own workspace package.

Landing redesign + /play

New styles, fonts, loading states, and the logo on the docs site. The bigger addition is the /play feature, which turns the framework into a small arcade—route matching treated as a game, an interactive environment leak-protection demonstration, and a static-versus-server call behaviour that you can click through. Two components have already been developed: leak-check (to provide a visual indication of the client/server boundary) and mode-call (comparing static and server rendering side by side).

There are six fixes, one adapter, one new page, and a bug resulting from two functions sharing a name rather too casually. Tomorrow: it will probably be more of the same.

0
0
12
Open comments for this post

4h 27m 24s logged

Devlog #5: why I built x

This all began when I was trying to launch my SaaS, autopermit (autopermit.vercel.app). whenever I clicked anything in Vercel’s dashboard, it was slow to respond.

I had previously worked with Astro and built a simple blog. That was a good learning experience, and I liked the speed of the frontend framework. however, I wanted strong backend performance like Next.js offered. I knew I could combine the backend of Next.js with the frontend of Astro, but I wasn’t sure how to make it work for me or why I needed to do it.

Then I found Bun, and everything became clear. Bun provided many important features right out of the box: bundler, runtime engine, package manager, and embedded database drivers. i realized i didn’t need to try to combine two heavyweight frameworks anymore.

Github Repo (Give it Star ⭐️): https://github.com/abdelkabirouadoukou/x
Website of FrameWork: https://thexjs.vercel.app/

0
0
30
Open comments for this post

2h 32m 10s logged

DevLog #4

I’ve built x (@thexjs), a single-process, full-stack React framework which runs native on Bun.

Project’s on StarDance: https://stardance.hackclub.com/home

Why

Next.js and the other tools come with Webpack or Vite, together with a development server and a lot of additional abstractions. Bun has already incorporated transpiling, bundling, package management, and native HTTP support , it even includes support for SQLite and Postgres. Which is why, rather than wrapping React around another bundler, I have built it to work directly with what Bun already provides.

What it does

The system is based on files just place a .tsx file in the src/pages/ directory and it becomes a route. Each route individually chooses whether to use SSR or static pre-rendering (by using the statement export const mode = “static”). The API routes are located in src/api/ and share their memory and database context with the rest of the application. Server functions enable you to call type-safe backend logic directly from within a component.

Regarding security, there is build-time leak detection based on AST so that secrets won’t end up in the client bundles, together with CSRF protection and rate limiting built in. For use in production, /healthz and /readyz are provided, along with JSON logging and support for OpenTelemetry and Sentry. The application can be deployed to a VPS, using Docker, or on Vercel via @thexjs/adapter-vercel.

Quickstart

bash
bun create thexjs-app@latest my-app
cd my-app
bun run dev

You get a working app in less than a minute.

Link: https://github.com/abdelkabirouadoukou/x

If you look around and happen upon anything that’s broken, then open an issue I’ll look into it.

0
0
24
Open comments for this post

52m 58s logged

Dev log #3

Shipped new features for x this week: a Vercel adapter, a real security layer, and observability that doesn’t depend on console.log.

Vercel adapter (@thexjs/adapter-vercel)

Deploying to Vercel used to require dealing with vercel.json or using runtime hacks. The adapter now connects directly to the build pipeline and creates a proper .vercel/output/ directory. Static hydration bundles and media go to the CDN. SSR routes and server actions get packaged into a standalone Node-compatible ESM function. A config.json manifest directs static files first with SSR as the backup. No configuration is needed.

Security

@thexjs/core now checks client bundles during the build. If a server-only environment variable, such as STRIPE_SECRET_KEY, slips through without the THEXJS_PUBLIC_ prefix, the build fails immediately—preventing any leaks. Server actions reaching /__x/actions/* get automatic Origin/Referer verification with support for double-submit cookies to protect against CSRF. There’s also built-in CSP, HSTS, and X-Frame-Options headers, along with a customizable in-memory rate limiter.

Observability

Logs are now structured as JSON, including timestamp, requestId, status, and durationMs. This format works with Datadog, Loki, or Grafana without needing to parse raw text. Added /healthz and /readyz endpoints run before route matching, for those using this in Kubernetes. The createSentryReporter and createOtelReporter hooks automatically catch unhandled SSR and action errors.

Config example:

import { createApp, createSentryReporter } from "@thexjs/core";
const app = createApp({
  pagesDir: "./src/pages",
  actionsDir: "./src/actions",
  security: {
    csrf: { allowedOrigins: ["https://app.example.com"] },
    headers: { contentSecurityPolicy: "default-src 'self'" },
    rateLimit: { limit: 100, windowMs: 60_000 },
  },
  observability: {
    logging: true,
    errorReporter: createSentryReporter(Sentry),
    health: { checks: { database: () => db.ping() } },
  },
});

Still working through the rest of the PRD. Routing, i18n, and caching are next.

0
0
24
Ship

Built “X” — a lightweight full-stack React framework powered natively by the Bun runtime.

In this update, I focused on getting the core Server-Side Rendering (SSR) pipeline smooth and ultra-fast. I refactored the dev server to make hot-reloading seamless, fixed routing edge cases, and polished the CLI so you can spin up a full-stack React app with zero-config overhead.

The goal is to keep modern React development fast, simple, and bloat-free by leveraging Bun’s speed.

  • 2 devlogs
  • 2h
  • 5.00x multiplier
  • 11 Stardust
Try project → See source code →
Open comments for this post

1h 38m 41s logged

Dev log #2

Log entry: I’ve been working over the past few days on SSR performance and sorting out the DX side.

I reduced the initial size of the payload and altered the way components hydrate, which as a result decreased response latency on the native Bun HTTP server. I refactored the startup CLI and improved hot module reloading, file changes now appear instantly rather than sometimes needing a restart.

A routing bug involving the parsing of query parameters which was causing problems with the serving of static assets in certain situations has also been fixed, and the way in which internal state is managed throughout the request lifecycle has been cleaned up.

What was annoying was the situation with concurrent requests when doing hot reloads since Bun would leave the state hanging between reloads, a problem that only became apparent under heavy load. It took some time to work out what was going on and in the end I added more detailed logging to detect the cases where the memory wasn’t being freed. The server now runs cleanly without the need for manual restarts, which was the real aim.

0
0
33
Loading more…

Followers

Loading…