A lightweight Tampermonkey userscript designed to modify X/Twitter's client-side age and sensitive-media feature state directly in the browser.
AgebypassX v2.4.0 uses a multi-layer state interception system covering:
window.__INITIAL_STATE__Object.assignJSON.parseResponse.prototype.json
The script runs entirely inside your browser. It does not send data to external servers, include analytics or tracking, or directly modify your X/Twitter account.
Note: Current versions do not use webpack chunk interception. Modern AgebypassX releases work by intercepting and patching application state and parsed response data before X's frontend consumes it.
- Install Tampermonkey or another compatible userscript manager.
- Install the AgebypassX userscript.
- Open or reload X/Twitter.
- A small green status dot should appear in the upper-right corner.
The script runs at:
document-start
so its hooks are installed as early as possible.
AgebypassX is designed to operate entirely locally.
The script:
- Does not send browsing data anywhere.
- Does not contact external APIs or servers.
- Does not contain analytics.
- Does not contain advertisements.
- Does not contain telemetry or tracking.
- Does not directly modify your X/Twitter account.
- Does not modify authentication cookies.
- Stores only the indicator visibility preference locally using
localStorage.
Everything happens inside the browser through the userscript.
The full source code is available for inspection.
Modern X/Twitter pages receive application configuration and feature information through several different state and response paths.
AgebypassX hooks those paths and patches selected client-side values before the frontend uses them.
The current version watches for:
rweb_age_assurance_flow_enabled
age_verification_gate_enabled
sensitive_tweet_warnings_enabled
sensitive_media_settings_enabled
grok_settings_age_restriction_enabled
rweb_mvr_blurred_media_interstitial_enabledThe current desired values are:
{
rweb_age_assurance_flow_enabled: false,
age_verification_gate_enabled: false,
sensitive_tweet_warnings_enabled: false,
sensitive_media_settings_enabled: true,
grok_settings_age_restriction_enabled: false,
rweb_mvr_blurred_media_interstitial_enabled: false
}AgebypassX supports multiple feature-state shapes.
Direct properties:
{
sensitive_media_settings_enabled: true
}Wrapped values:
{
sensitive_media_settings_enabled: {
value: true
}
}GraphQL-style feature entries:
{
feature: "sensitive_media_settings_enabled",
enabled: true
}The patcher recursively searches relevant state objects while using a per-patch WeakSet to protect against circular references.
X may represent feature-switch values using different types.
For example, a value may appear as:
trueor:
"true"or occasionally:
1AgebypassX v2.4.0 preserves the original representation when applying the desired boolean state.
Examples:
boolean β boolean
string β "true" / "false"
number β 1 / 0
This avoids breaking frontend code which performs strict comparisons against the original value type.
v2.4.0 no longer assumes that assigning a value means the write succeeded.
Target-feature modifications use a verified write process:
Read current value
β
Determine correctly typed desired value
β
Attempt assignment
β
Read value back
β
Verify that the new value actually stuck
This catches cases such as:
- Frozen objects.
- Non-writable properties.
- Throwing setters.
- Setters which accept a value but silently discard it.
- Unexpected application-state behaviour.
Successful writes are recorded separately from failed writes in the diagnostics.
AgebypassX also patches compatible client-side birthdate objects to an adult date:
{
year: 1990,
month: 1,
day: 1
}Birthdate writes are:
- Type-preserving.
- Verified after assignment.
- Independently counted in diagnostics.
Existing numeric values remain numbers:
1995 β 1990
Existing string values remain strings:
"1995" β "1990"
Missing birthdate fields are filled using numeric values.
AgebypassX installs an accessor on:
window.__INITIAL_STATE__When X assigns its initial application state, the object is patched before the frontend consumes it.
Although the script runs at document-start, userscript injection timing can occasionally vary.
v2.4.0 therefore checks whether:
window.__INITIAL_STATE__already exists before installing the hook.
If an existing state object is found:
- Its current value is preserved.
- The existing object is patched.
- The accessor is installed using that preserved value.
This avoids replacing already-populated application state with undefined.
If reading an existing __INITIAL_STATE__ property itself throws, AgebypassX does not replace it.
Instead, Hook 1 is left untouched and the remaining interception layers continue operating.
Some application state is created or updated dynamically after initial page load.
AgebypassX wraps:
Object.assignand checks state-like targets containing structures such as:
featureSwitch
entities
users
Relevant objects are patched after the native assignment completes.
Some application state is created from JSON strings.
AgebypassX wraps:
JSON.parseBefore recursively walking the parsed object, the original JSON text is checked using a single regular-expression gate.
The gate looks for:
- Known target feature names.
birthdatefeatureSwitch
If nothing relevant is present, the object is returned without a deep traversal.
Modern X code frequently uses:
fetch(...)followed by:
response.json()Browser-native Response.json() parsing can bypass an overridden page-level JSON.parse.
AgebypassX therefore also wraps:
Response.prototype.jsonReturned objects are inspected using a lightweight structural scan before the full patcher runs.
The current structural pre-scan depth is:
5
A full recursive patch only occurs when potentially relevant state is detected.
AgebypassX is designed to avoid blindly scanning everything X creates.
Before recursively walking data returned through JSON.parse, the script performs a single regex search for:
- Target feature names.
birthdatefeatureSwitch
If none are present, no recursive patch is performed.
Objects returned through Response.json() use a depth-limited structural scan before the full patcher runs.
AgebypassX does not use:
- Continuous polling.
- Scroll listeners.
- Repeating patch timers.
- Per-tweet processing loops.
- Webpack module rewriting.
Patching occurs only when one of the hooked data paths is triggered.
X is a Single Page Application.
Large parts of the application can change without a traditional page reload.
AgebypassX creates a new:
WeakSetfor every patch operation.
This gives cycle protection during one traversal while still allowing the same state object to be patched again later if X repopulates or modifies it.
AgebypassX wraps several native JavaScript functions.
To reduce compatibility problems, replacement functions preserve the original function's:
.name
.length
For example:
JSON.parse.namecontinues to behave like:
parse
and:
Object.assign.namecontinues to behave like:
assign
AgebypassX intentionally does not currently add more aggressive anti-detection or Function.prototype.toString spoofing.
There is no evidence that this is required for current functionality, and avoiding unnecessary interception keeps the implementation simpler and more maintainable.
AgebypassX displays a small status indicator in the top-right corner.
π’ ACTIVE
The current interception and traversal system is operating without a detected traversal/hook error.
A successful later gated patch can restore the indicator to green after a transient error.
π΄ ERROR
A hook installation or recursive traversal operation encountered an error.
Check the browser console for messages beginning with:
[Nox]
The dot represents hook/traversal health.
Individual feature writes which fail or do not stick are tracked separately in diagnostics and do not automatically turn the dot red.
This distinction allows the script to report:
Hooks operational
while separately showing:
Specific feature write failed
Click the green/red indicator dot to print AgebypassX diagnostics to the browser console.
The diagnostics include:
Current ACTIVE / ERROR status
Total historical hook/traversal errors
Gate-hit counters
Feature flags found
Feature flags successfully changed
Feature processing/write failures
Birthdate statistics
Potential related/unknown keys
Recent errors
AgebypassX tracks how many relevant patch attempts came from:
state
assign
parse
json
These correspond to:
__INITIAL_STATE__
Object.assign
JSON.parse
Response.json
This helps identify which interception paths are actually being used by the current X frontend.
Three counters are tracked for every known target flag.
How many times the feature was encountered.
How many times its value needed changing and the new value was successfully verified after assignment.
How many times the feature could not be completely processed or written.
This can include:
- Property reads which throw.
- Assignment failures.
- Non-writable properties.
- Read-back mismatches.
- Setters which discard the requested value.
found > 0
changed > 0
writeFailed = 0
Means:
Working normally.
found > 0
changed = 0
writeFailed = 0
Means:
The flag was found but already had the desired value.
found > 0
writeFailed > 0
Means:
The flag exists, but one or more processing/write attempts did not complete successfully.
found = 0
Means:
The flag was not encountered during this session.
This is a warning signal, not proof of removal.
Possible explanations include:
- X renamed the feature.
- The feature is region-specific.
- The account is not part of the relevant experiment.
- The endpoint containing the feature was never loaded.
- X removed the feature.
- X moved the configuration elsewhere.
Birthdate handling has its own counters:
seen
changed
failed
Number of compatible birthdate objects encountered.
Number of individual birthdate fields successfully changed and verified.
Number of individual birthdate field writes which threw or failed read-back verification.
AgebypassX also includes a lightweight diagnostic scanner which looks for potentially related keys containing terms such as:
age
birth
minor
sensitive
blur
restrict
verif
interstitial
Potential matches are logged once per session.
These keys are displayed as:
related keys seen near known structures (NOT verified flags)
This is not a complete automatic feature-renaming detector.
The scanner only runs while traversing state that was already reached through one of AgebypassX's known gates.
If X completely renames both a feature and the surrounding structure, the scanner may never encounter it.
The found = 0 counters remain an important signal when investigating possible frontend changes.
Click the status dot and open DevTools Console.
You may see something similar to:
[Nox] diagnostics v2.4.0
status: ACTIVE | total errors: 0
gate hits:
{
state: 1,
assign: 4,
parse: 2,
json: 7
}
flags found:
{
rweb_age_assurance_flow_enabled: 2,
age_verification_gate_enabled: 0,
sensitive_tweet_warnings_enabled: 3,
sensitive_media_settings_enabled: 3,
grok_settings_age_restriction_enabled: 1,
rweb_mvr_blurred_media_interstitial_enabled: 0
}
flags changed:
{
...
}
flag process/write failures:
{
...
}
birthdate:
{
seen: 2,
changed: 3,
failed: 0
}
Actual values depend on:
- Account configuration.
- Region.
- Experiments.
- Which X pages were visited.
- Which API responses were loaded.
Press:
Alt + .
to show or hide the indicator.
The preference is stored locally using:
localStorageand persists across page reloads.
No external server receives this setting.
Because the userscript runs at:
document-start
the page DOM may not yet exist when execution begins.
The indicator waits until:
document.documentElementis available before mounting.
A MutationObserver watches the document root for removal of the indicator.
If the dot disappears, AgebypassX mounts it again.
Try:
- Press Alt + . in case the indicator was previously hidden.
- Confirm Tampermonkey is enabled.
- Confirm AgebypassX is enabled.
- Confirm the script has permission to run on:
https://x.com/*
https://twitter.com/*
- Reload the page.
Open DevTools:
F12 β Console
Search for:
[Nox]
You should normally see messages similar to:
[Nox] v2.4.0 loaded
[Nox] ready β click the dot for diagnostics
If there are no AgebypassX messages at all, the userscript may not be executing.
Check the userscript manager and site permissions.
A red indicator means the hook/traversal system encountered an error.
Possible console messages include:
[Nox] Existing state capture failed
[Nox] __INITIAL_STATE__ hook failed
[Nox] State patch failed
[Nox] Object.assign patch failed
[Nox] JSON.parse patch failed
[Nox] Response.json hook failed
[Nox] walk failed
Click the dot to print the full recent-error diagnostics.
Include relevant messages when opening a bug report.
A green indicator does not guarantee that every target flag still exists or that X still relies on client-side enforcement.
Click the indicator and inspect:
flags found
flags changed
flag process/write failures
birthdate
gate hits
X may have:
- Renamed a feature flag.
- Changed its response format.
- Moved configuration to another state path.
- Region-gated a feature.
- Added or changed experiments.
- Added server-side enforcement.
- Changed how the frontend consumes feature state.
The diagnostic counters are designed to make these cases easier to identify.
AgebypassX has primarily been tested with Chromium-based browsers.
Examples include:
- Google Chrome
- Chromium
- Microsoft Edge
- Brave
Tampermonkey and Violentmonkey-compatible environments should generally work, but userscript-manager behaviour can differ between browsers.
The script safely guards its use of:
GM_infoand falls back to the hardcoded script version if unavailable.
Open DevTools and filter for:
[Nox]
[Nox] v2.4.0 loaded
The userscript has started executing.
[Nox] ready β click the dot for diagnostics
Hook installation code has completed.
Errors use messages such as:
[Nox] JSON.parse patch failed
The diagnostics retain up to the most recent:
20
errors.
Console warning output is rate-limited to avoid excessive spam.
Bug reports are welcome.
Open an issue:
https://github.com/Saganaki22/AgebypassX/issues
Please include:
- Browser name.
- Browser version.
- Userscript manager.
- Userscript manager version.
- AgebypassX version.
- Current dot status.
gate hitsdiagnostics.flags founddiagnostics.flags changeddiagnostics.flag process/write failures.- Birthdate diagnostics if relevant.
- Related-key diagnostics if present.
- Relevant
[Nox]errors. - Description of what happened.
- Steps required to reproduce the issue.
Please remove personal information from screenshots or console output before posting it publicly.
AgebypassX is open source.
Repository:
https://github.com/Saganaki22/AgebypassX
The complete userscript can be inspected before installation.
AgebypassX is licensed under the MIT License.
You are free to inspect, modify, fork, and redistribute the project under the terms of the license.
https://opensource.org/licenses/MIT
Feedback, bug reports, pull requests, and improvements are welcome.
GitHub:
https://github.com/Saganaki22/AgebypassX
If X changes its frontend architecture or feature configuration, reports containing the new v2.4.0 diagnostic counters can help identify what changed.
Feature modifications now preserve X's existing representation.
Supported forms include:
boolean β boolean
string β "true" / "false"
number β 1 / 0
This improves compatibility with feature-switch structures that use strict type comparisons.
Target-feature assignments are now read back after modification.
The script separately tracks:
found
changed
writeFailed
so diagnostics can distinguish between:
- A feature not being present.
- A feature already having the desired value.
- A successful modification.
- A modification which threw or did not stick.
Clicking the indicator now prints detailed diagnostics to the browser console.
Diagnostics include:
Current health
Historical errors
Per-hook gate counts
Per-flag found counts
Per-flag changed counts
Per-flag processing/write failures
Birthdate statistics
Potential related keys
Recent errors
Known feature counters are pre-seeded with 0, making features which were not encountered immediately visible.
Birthdate handling now uses:
- Type-preserving scalar conversion.
- Verified assignment.
- Read-back validation.
The script tracks:
birthdate.seen
birthdate.changed
birthdate.failed
The indicator now separates:
Hook/traversal health
from:
Individual feature-write outcomes
A transient hook/traversal error can recover to green after a genuinely successful gated patch.
Unrelated JSON.parse, Object.assign, or response activity cannot falsely clear an error state.
Recursive traversal now propagates internal traversal failures back to the originating hook.
A hook only reports successful recovery when its gated patch completed without a traversal error.
Added heuristic discovery of potentially related keys containing terms such as:
age
birth
minor
sensitive
blur
restrict
verif
interstitial
This helps investigate X frontend changes while clearly distinguishing candidates from verified feature flags.
If AgebypassX starts after X has already populated:
window.__INITIAL_STATE__the existing value is captured and patched before the accessor is installed.
If capturing the existing property fails, AgebypassX leaves it untouched rather than risking state corruption.
Hooks 2β4 remain operational as fallback interception paths.
The current implementation is described accurately as application-state and parsed-response interception.
Webpack interception is not used or required by v2.4.0.
Added:
Alt + .
to show or hide the status indicator.
The preference persists locally across reloads.
Added a single-pass regular-expression gate for raw JSON payloads.
Deep recursive walks are only performed when potentially relevant feature names are detected.
Response.json() results use a lightweight depth-limited structural scan before the full object patcher runs.
This substantially reduces unnecessary traversal of unrelated responses.
Added interception for:
Response.prototype.jsonbecause browser-native fetch response parsing can bypass an overridden JSON.parse.
Cycle detection became scoped to individual patch operations.
State objects can therefore be patched again if X repopulates them after SPA navigation.
Improved indicator mounting for document-start.
The indicator is automatically restored if the page removes it.
Wrapped native functions preserve their original:
.name
.length
values.
Added support for:
{
feature: "feature_name",
enabled: true
}Introduced interception through:
__INITIAL_STATE__
Object.assign
JSON.parse
Added the green/red status indicator.
Improved protection against:
- Circular object graphs.
- Throwing getters.
- Non-writable properties.
- Unexpected application objects.
- DOM objects.
- Browser globals.
Introduced webpack chunk interception for the X frontend architecture used at the time.
Added targeting for sensitive-media-related frontend modules and queries.
Added improved debugging and status information.
Added additional interception strategies for network and GraphQL-related paths.
Expanded the status indicator and debugging interface.
Added additional console information and debugging tools.
The architecture introduced in v1.3.0 should not be confused with modern AgebypassX releases. v2.x now uses application-state and response interception instead of webpack chunk interception.
- Added configuration and state-management improvements.
- Added multiple patching strategies.
- Improved user interface behaviour.
- Improved SPA navigation handling.
- Added fallback patching methods.
- Improved error handling.
- Expanded patch targets.
- Initial release.
- Basic client-side age-state patching.
- Basic status indicator.
AgebypassX is an independent open-source project and is not affiliated with, endorsed by, or associated with X Corp., Twitter, Tampermonkey, or Violentmonkey.
The project modifies client-side application state only.
X may change its frontend, feature flags, experiments, response structures, or introduce additional server-side enforcement at any time, which may cause some or all functionality to stop working.
Use the software at your own discretion and comply with the laws, platform rules, and age requirements applicable to you.