Skip to content

Revenge Next TypeScript & Hermes Development

Hermes plugins execute within Discord\'s React Native engine (Hermes Bytecode v96).


1. Plugin Entrypoint (src/index.tsx)

import React from 'react';
import { before, after } from '@revenge-mod/patcher';
import { getModuleWithImportedPath } from '@revenge-mod/discord/utils/modules/finders';
import Settings from './ui/Settings';

declare const plugin: <T = any>(def: any) => any;
declare const revenge: any;

const DEFAULT_SETTINGS = {
    enabled: true,
    customLabel: 'Default'
};

export default plugin({
    jsonStorage: {
        load: true,
        default: DEFAULT_SETTINGS
    },

    start(api) {
        const getSettings = () => ({
            ...DEFAULT_SETTINGS,
            ...(api.jsonStorage.get() ?? {})
        });

        const targetModule = getModuleWithImportedPath('modules/chat/native/MessageView.tsx');
        if (targetModule) {
            const Host = targetModule.default ?? targetModule;

            api.cleanup(
                before(Host, 'render', (args) => {
                    try {
                        if (getSettings().enabled) {
                        }
                    } catch (err) {
                    }
                    return args;
                })
            );
        }

        const Dispatcher = (revenge as any)?.discord?.flux?.Dispatcher;
        if (Dispatcher?.subscribe) {
            const handleMessage = (event: any) => {};
            Dispatcher.subscribe('MESSAGE_CREATE', handleMessage);
            api.cleanup(() => Dispatcher.unsubscribe('MESSAGE_CREATE', handleMessage));
        }
    },

    SettingsComponent: Settings
});

2. Chat Interception via NativeChatModule

import { getNativeModule } from '@revenge-mod/modules/native';
import { before } from '@revenge-mod/patcher';

const chatModule = getNativeModule<any>('NativeChatModule') || getNativeModule<any>('DCDChatManager');

if (chatModule?.updateRows) {
    api.cleanup(
        before(chatModule, 'updateRows', (args) => {
            try {
                const jsonStr = typeof args[1] #### 'string' ? args[1] : (typeof args[0] 'string' ? args[0] : null);
                if (jsonStr) {
                    const rows = JSON.parse(jsonStr);
                    if (Array.isArray(rows)) {
                        for (const row of rows) {
                            if (row?.type === 1 && row.message) {
                            }
                        }
                        if (typeof args[1] === 'string') args[1] = JSON.stringify(rows);
                        else args[0] = JSON.stringify(rows);
                    }
                }
            } catch (err) {
            }
            return args;
        })
    );
}

3. Bundling with @revenge-mod/plugin-cli

bun run build <plugin-name>