Description
choc_javascript_V8.h doesn't compile against current V8 (we're on 15.1.x). It calls a few V8 APIs that were deprecated and then removed in newer V8, so the V8 backend only builds against older V8 headers:
v8::String::Utf8Length(isolate) and v8::String::WriteUtf8(isolate, ...) the v1 UTF-8 accessors are gone; V8 replaced them with Utf8LengthV2 / WriteUtf8V2.
v8::Context::GetIsolate() removed; you now get the isolate via v8::Isolate::GetCurrent() (or by threading it through).
None of this is a bug in choc's logic it's just API drift in V8. The QuickJS/JSC backends are unaffected; this is V8-only.
Where it is
v8StringToStd() (around line 456):
auto len = s.Utf8Length (isolate);
result.resize (static_cast<std::string::size_type> (len));
s.WriteUtf8 (isolate, result.data(), len);
Utf8Length / WriteUtf8 no longer exist on v8::String in current V8.
- The two module-resolve callbacks (the dynamic-import one around line 107 and the
InstantiateModule one around line 522) both do:
return static_cast<V8Context*> (c->GetIsolate()->GetData (0))->loadDynamicModule (...);
c->GetIsolate() v8::Context::GetIsolate() was removed.
What we did (workaround)
To build against V8 15.1 we changed those call sites to the newer APIs:
// v8StringToStd
auto len = s.Utf8LengthV2 (isolate);
result.resize (static_cast<std::string::size_type> (len));
s.WriteUtf8V2 (isolate, result.data(), result.size(),
v8::String::WriteFlags::kReplaceInvalidUtf8);
// in the resolve callbacks
static_cast<V8Context*> (v8::Isolate::GetCurrent()->GetData (0))->loadDynamicModule (...);
That compiles and runs fine for us on 15.1, but it would break older V8 (the V2 methods don't exist there), so it's not something we can just drop in unconditionally.
Possible fix direction
A version guard would let one copy of the header build against both old and new V8. V8_MAJOR_VERSION is available from v8-version.h / v8config.h, so something like:
#if V8_MAJOR_VERSION >= 13 // (whatever the first version with the V2 API is)
auto len = s.Utf8LengthV2 (isolate);
result.resize (static_cast<std::string::size_type> (len));
s.WriteUtf8V2 (isolate, result.data(), result.size(),
v8::String::WriteFlags::kReplaceInvalidUtf8);
#else
auto len = s.Utf8Length (isolate);
result.resize (static_cast<std::string::size_type> (len));
s.WriteUtf8 (isolate, result.data(), len);
#endif
and the same idea for c->GetIsolate() vs v8::Isolate::GetCurrent(). You'll know the exact V8 version cutoffs better than I do as I only verified the new side against 15.1.
Happy to share the exact diff we're using if it's helpful, but I figured you'd rather pick the version boundaries yourself.
Environment
- CHOC: latest main (June 2026)
- V8: 15.1.27 (built standalone, monolithic, Intl on)
- Compiler: Clang (the V8-bundled clang), C++20
- OS: macOS 26 / Linux same compile errors on both
Appendix
If it helps with testing, I’ve got precompiled V8 builds available here: https://github.com/danielraffel/v8-builder
Description
choc_javascript_V8.hdoesn't compile against current V8 (we're on 15.1.x). It calls a few V8 APIs that were deprecated and then removed in newer V8, so the V8 backend only builds against older V8 headers:v8::String::Utf8Length(isolate)andv8::String::WriteUtf8(isolate, ...)the v1 UTF-8 accessors are gone; V8 replaced them withUtf8LengthV2/WriteUtf8V2.v8::Context::GetIsolate()removed; you now get the isolate viav8::Isolate::GetCurrent()(or by threading it through).None of this is a bug in choc's logic it's just API drift in V8. The QuickJS/JSC backends are unaffected; this is V8-only.
Where it is
v8StringToStd()(around line 456):Utf8Length/WriteUtf8no longer exist onv8::Stringin current V8.InstantiateModuleone around line 522) both do:c->GetIsolate()v8::Context::GetIsolate()was removed.What we did (workaround)
To build against V8 15.1 we changed those call sites to the newer APIs:
That compiles and runs fine for us on 15.1, but it would break older V8 (the V2 methods don't exist there), so it's not something we can just drop in unconditionally.
Possible fix direction
A version guard would let one copy of the header build against both old and new V8.
V8_MAJOR_VERSIONis available fromv8-version.h/v8config.h, so something like:and the same idea for
c->GetIsolate()vsv8::Isolate::GetCurrent(). You'll know the exact V8 version cutoffs better than I do as I only verified the new side against 15.1.Happy to share the exact diff we're using if it's helpful, but I figured you'd rather pick the version boundaries yourself.
Environment
Appendix
If it helps with testing, I’ve got precompiled V8 builds available here: https://github.com/danielraffel/v8-builder