{"id":4826,"url":"https://github.com/jondot/rn-snoopy","last_synced_at":"2025-04-05T11:10:21.865Z","repository":{"id":47586592,"uuid":"64055220","full_name":"jondot/rn-snoopy","owner":"jondot","description":"Snoopy is a profiling tool for React Native, that lets you snoop on the React Native Bridge.","archived":false,"fork":false,"pushed_at":"2021-08-23T06:43:52.000Z","size":4268,"stargazers_count":522,"open_issues_count":3,"forks_count":29,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-03-29T10:08:40.368Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jondot.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-07-24T08:03:37.000Z","updated_at":"2025-03-24T07:12:35.000Z","dependencies_parsed_at":"2022-08-31T01:01:54.034Z","dependency_job_id":null,"html_url":"https://github.com/jondot/rn-snoopy","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jondot%2Frn-snoopy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jondot%2Frn-snoopy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jondot%2Frn-snoopy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jondot%2Frn-snoopy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jondot","download_url":"https://codeload.github.com/jondot/rn-snoopy/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247325693,"owners_count":20920714,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-01-05T20:17:25.367Z","updated_at":"2025-04-05T11:10:21.833Z","avatar_url":"https://github.com/jondot.png","language":"JavaScript","funding_links":[],"categories":["Utilities","JavaScript"],"sub_categories":["Other Platforms"],"readme":"# React Native Snoopy\n\n\u003ch3 align=\"center\"\u003e\n  \u003cimg src=\"media/snoopy.png\" alt=\"Snoopy\" width=\"215px\"/\u003e\n  \u003cbr/\u003e\n  \u003cbr/\u003e\n\u003c/h3\u003e\n\u003cbr/\u003e\n\u003cbr/\u003e\n\n_UPDATE_: I wrote [an article](https://medium.com/@jondot/debugging-react-native-performance-snoopy-and-the-messagequeue-fe014cd047ac) with the story behind this library.\n\nSnoopy is a profiling tool for React Native, that lets you snoop on the React Native Bridge using the [MessageQueue spy feature](https://github.com/facebook/react-native/pull/9160).\n\nWith Snoopy you can tame a stream of events, using\n[Rx](https://github.com/Reactive-Extensions/RxJS) and a few built-in goodies,\nto locate performance hogs, problems, and expose unexpected communications on the bridge.\n\n\nThe React Native bridge is the hub where communication between the Javascript\nand the Native world happen. Optimizing and catching unexpected (bad)\ncommunications can make or break your performance. Being that central and\nsensitive place, it made sense to have tooling built around it.\n\n*NOTE*: Snoopy is a developer tool, and you might want to flag it under `__DEV__`. I felt\nnot doing this by default inside Snoopy will allow for creative uses even in production.\n\n\n\u003ch3 align=\"center\"\u003e\n  \u003cimg src=\"media/snoopy.gif\" alt=\"Aggregating and Charting Events with Bar\" width=\"400px\"/\u003e\n  \u003cimg src=\"media/snoopy-filter.gif\" alt=\"Filtering Create Views Only\" width=\"400px\"/\u003e\n  \u003cbr/\u003e\n  \u003cbr/\u003e\n\u003c/h3\u003e\n\n\n## Quick Start\n\n```\n$ npm install -S rn-snoopy\n```\n\nFirst, find a place to initialize Snoopy and the event stream, doesn't matter where, but\npreferably under an `if(__DEV__)` guard.\n\n```javascript\n// core Snoopy\nimport Snoopy from 'rn-snoopy'\n\n// some Snoopy goodies we're going to use\nimport bars from 'rn-snoopy/stream/bars'\nimport filter from 'rn-snoopy/stream/filter'\nimport buffer from 'rn-snoopy/stream/buffer'\n\nimport EventEmitter from 'react-native/Libraries/vendor/emitter/EventEmitter';\n\n//If you are using React 0.48 or below, then you should import:\n//import EventEmitter from 'react-native/Libraries/EventEmitter/EventEmitter';\n\nconst emitter = new EventEmitter()\n\nconst events = Snoopy.stream(emitter)\n```\n\nIn the following examples, we're going to use `info`, the call descriptor.\n\n```javascript\n{\n  type: int (0=N-\u003eJS, 1=JS-\u003eN)\n  method: string,\n  module: string,\n  args: object,\n}\n```\n\n\n\n\n## Examples\n\nShow only calls going from Javascript to Native create an `info` shape with\n`Snoopy.TO_NATIVE`. Use `true` to log filter results.\n\n```javascript\nfilter({ type: Snoopy.TO_NATIVE }, true)(events).subscribe()\n```\n\nShow calls to `createView`. Filter based on `method`, and provide a shape to match it.\n\n```javascript\nfilter({ method:'createView' }, true)(events).subscribe()\n```\n\nDrill down and show only calls with specific arguments, using nested matching.\n\n```javascript\nfilter({ method:'createView', {args: {foo: {bar:1}}}}, true)(events).subscribe()\n```\n\nOr use a function.\n\n```javascript\nfilter((info)=\u003einfo.method == 'createView', true)(events).subscribe()\n```\n\nVisualize \"excessive\" calls across the bridge. Group and aggregate calls per second.\n\n```javascript\nbars()(\n  buffer()(\n    events\n  )\n).subscribe()\n```\n\n\n\nVisualize \"heavy\" calls across the bridge. Use a heuristic: serialize arguments and take\nthe size.\n\n```javascript\nbars(info=\u003eJSON.stringify(info.args).length)(\n  events\n).subscribe()\n```\n\n\nVisualize \"heavy\" calls across the bridge. Set a threshold (`100`) and pop a Yellowbox (`true`) in Simulator\nto warn about crossing the threshold.\n\n```javascript\nbars(info=\u003eJSON.stringify(info.args).length,\n  200 /*command string length threshold*/,\n  true /*show yellow box*/\n)(events).subscribe()\n```\n\n\nVisualize \"heavy\" calls, only for view creation. This filters on `createView` and takes a look at the\nargument data size.\n\n```javascript\nbars(info=\u003eJSON.stringify(info.args).length)(\n    filter({ method:'createView' })(events)\n).subscribe()\n```\n\n# React Native Below 0.33\n\nI've submitted a modification to `MessageQueue` that allows for more flexible bridge spy,\nwhich was made available starting React Native v0.33. Versions 0.33 and up will work seamlessly with Snoopy.\n\nFor versions below 0.33, you have the option of locking to a legacy version of Snoopy which\ninstalls the required `MessageQueue` modifications by patching it externally:\n\n```\n$ npm i rn-snoopy@1.0.6\n```\n\n# Contributing\n\nFork, implement, add tests, pull request, get my everlasting thanks and a respectable place here :).\n\n\n### Thanks:\n\nTo all [Contributors](https://github.com/jondot/rn-snoopy/graphs/contributors) - you make this happen, thanks!\n\n\n\n# Copyright\n\nCopyright (c) 2016 [Dotan Nahum](http://gplus.to/dotan) [@jondot](http://twitter.com/jondot). See [LICENSE](LICENSE.txt) for further details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjondot%2Frn-snoopy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjondot%2Frn-snoopy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjondot%2Frn-snoopy/lists"}