Summary
This is a strawperson proposal to introduce direct memory allocation hints into JavaScript. Unlike the "Types as Comments" proposal, which is intentionally ignored by engines, hinted.js provides optional syntax for "blind" engine optimization.
The Problem
Writing high-performance, memory-efficient JavaScript (for AI, video processing, or games) currently requires verbose ArrayBuffer and DataView boilerplate. Engines must speculatively guess object "shapes," leading to expensive de-optimization cliffs when those shapes change.
The Solution
Provide native syntax to declare fixed-width primitives and locked object layouts. The engine is not required to "verify" these types for safety; it is simply invited to "blindly" trust them for optimized memory allocation and access.
Key Examples:
Fixed-Width Primitives:
let n: int 1 = 3; //(8-bit signed) or
let g: bit = 1; // a sigle bit
Locked Object Shapes:
type User: {
id: int 4,
flags: bit,
name: str 10
};
let player: type User = { id: 1, name: 'dragon' };
Inheritance: Functions and Arrays can extend object types to gain fixed-size .props without losing their native behavior.
Why This?
Zero-Cost Abstraction: No runtime type-checking overhead; just direct allocation.
Backward Compatible: Unsupported engines can ignore the : annotations.
Efficiency: Drastically reduces "Hidden Class" overhead and memory fragmentation.
Note on Implementation: While bit-level or sub-byte allocations might be stored as full bytes internally for performance/alignment, the engine interfaces the data as if it were the specified size. The engine is simply invited to "blindly" trust these hints to optimize the memory layout without needing to verify logic at runtime.
This is quite an interesting idea! However implementing this might be difficult. Not just because it is something new, but rather requires refactoring existing code.
If we take a look at looping over Uint8Array, it is slower than looping over number[] (I know it from jsbenchmark.com). Each access of uint8 includes concersion uint8 → js number. Implementing integers in js means completely changing JavaScript numbers. Not only js side, but also V8 API, N-API and many others.
I agree that “strip-types” proposal is not viable at all and we need type-safe language. But making “typescript for runtime and not compile time” is easier than “int” introduction.
I’ve actually updated the proposal specifically to address this architectural concern. Originally, I looked at this as syntactic sugar for TypedArrays, but I’ve moved toward a Parallel Hinted Heap model to avoid the exact pitfalls you're describing.
The goal isn't to change how JS numbers work globally—which would be an architectural nightmare for V8 and N-API—but to provide a 'fast-track' lane:
Direct Register Use: Inside a loop, a hinted uint stays as raw bits in the CPU register. It bypasses the 'Box-and-Promote' cycle entirely because it never becomes a JS Number object while it's in that high-speed context.
Compatibility via Tagging: To support existing N-API and V8 structures without a rewrite, it uses Pointer Tagging. This allows the engine to use a single CPU instruction (OR/SHIFT) to make those raw bits 'look' like a standard integer to the rest of the system only when they need to 'cross the bridge' back to standard JS.
It’s less about 'Runtime Types' and more about providing a C++-style memory mapping that the JIT can finally treat as a fixed shape. It avoids the engine-wide rewrite by keeping hinted variables isolated from the standard JS heap.
Sorry for me being lazy))) I didn’t really check the repo and was making prejudices. Actually the idea introduce not a change, but new functionality. The idea is interesting (INCREDIBLE) and backward-compatible. The only constraint is that it is enormous and it is difficult to find the starting point. It feels more like creating another language rather than changing existing.
If we want js to be fast we need to find a way to make that change seamless (for V8 devs and TC39), introduce modifications one by one. For example, I have an idea of proposing (you can find that in my profile) ArrayBuffer.prototype.detach, which for implementation needs ONLY copy-pasting ArrayBuffer.prototype.transfer and stripping it from anything related to copying data between arraybuffers. But JSON.parseBinary one has no implementation steps suggested yet, so I guess I have more work to do.