xrmfastdev
v0.1.0
Published
WebSocket proxy server for Power Apps local development - bridges to Chrome via CDP
Maintainers
Readme
xrmfastdev
WebSocket proxy server for Power Apps local development. It bridges requests from
xrmfastdev-client's
ProxyXrmAdapter to a real, logged-in Chrome session via the Chrome DevTools
Protocol — so your localhost app talks to live Dataverse with no CORS
issues and no mocking.
Part of XRM Fast Dev.
Install
npm install --save-dev xrmfastdevShips a xrmfastdev-proxy bin, so you can also run it with npx xrmfastdev-proxy.
Usage
1. Start Chrome with remote debugging
chrome.exe --remote-debugging-port=9222 \
--user-data-dir="%USERPROFILE%\XrmDevProfile" \
https://your-org.crm.dynamics.comLog in to your Model-Driven App or Power Pages portal in that window.
2. Start the proxy
npx xrmfastdev-proxy --verboseExpected output:
=== XRM Fast Dev - Proxy Server ===
Configuration:
Chrome CDP Port: 9222
WebSocket Port: 8080
Verbose: true
[CDP] Connecting to Chrome at http://localhost:9222...
[CDP] Connected to Chrome browser
[CDP] Found Power Apps tab: https://your-org.crm.dynamics.com/...
[CDP] Detected page type: model-driven
✓ Proxy server is ready!
Clients can connect to: ws://localhost:8080CLI options
Usage: xrmfastdev-proxy [options]
--cdp-port <port> Chrome DevTools Protocol port (default: 9222)
--ws-port <port> WebSocket server port (default: 8080)
--verbose, -v Enable verbose logging
--help, -h Show this help messageProgrammatic usage
import { CdpClient, WebSocketServer } from 'xrmfastdev';
const cdpClient = new CdpClient({ cdpPort: 9222, verbose: true });
await cdpClient.connect();
const wsServer = new WebSocketServer(cdpClient, { port: 8080, verbose: true });
wsServer.start();
process.on('SIGINT', async () => {
wsServer.stop();
await cdpClient.disconnect();
process.exit(0);
});How it works
The proxy auto-detects the page type of the connected Chrome tab:
- Model-Driven App (
window.Xrm.WebApipresent) — callsXrm.WebApi[method](...)directly. - Power Pages Portal (
window.webapipresent) — issuesfetch('/_api/...')requests, automatically attaching the__RequestVerificationTokenfor POST/PATCH/PUT/DELETE.
Each WebSocket request { id, method, args } is executed in the browser via
page.evaluate() and answered with { id, success, result | error }.
Requirements
- Node.js >= 18
- Google Chrome / Chromium started with
--remote-debugging-port - Runtime dependencies:
puppeteer-core,ws
Troubleshooting
| Symptom | Fix |
|---------|-----|
| ECONNREFUSED on 9222 | Chrome isn't running with --remote-debugging-port=9222; use a separate --user-data-dir. |
| "No Power Apps tab found" | Navigate to a Model-Driven App or portal page and log in, then retry. |
| Portal mutations return 401/403 | The anti-forgery token wasn't found — refresh the portal page so the hidden __RequestVerificationToken input is present. |
License
MIT © Albert Halchanskyi
