# periscopic

> periscopic

Latest version **4.0.3** (published 2026-04-21) · MIT license · 0 weekly downloads

## Install

```sh
npm install periscopic
pnpm add periscopic
yarn add periscopic
bun add periscopic
```

## Health

**Score 65/100 (B)** — status: active.

Positive: has types; esm support; no vulnerabilities; has provenance; high quality score.

Warnings: low downloads.

## Facts

| | |
|---|---|
| Version | 4.0.3 |
| Published | 2026-04-21 |
| First published | 2019-09-08 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 3 |
| Unpacked size | 10.8 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Provenance | attested (GitHub Actions) |
| GitHub stars | 108 |
| Maintainers | rich_harris |

## Links

- npm: https://www.npmjs.com/package/periscopic
- Repository: https://github.com/Rich-Harris/periscopic
- Homepage: https://github.com/Rich-Harris/periscopic#readme
- Issues: https://github.com/Rich-Harris/periscopic/issues
- npm.io page: https://npm.io/package/periscopic

## Dependencies (3)

- [zimmerframe](https://npm.io/package/zimmerframe.md) ^1.0.0
- [is-reference](https://npm.io/package/is-reference.md) ^3.0.2
- [@types/estree](https://npm.io/package/@types/estree.md) *

## Recent versions

- 4.0.3 (latest) — 2026-04-21
- 4.0.2 — 2023-09-10
- 4.0.1 — 2023-09-10
- 4.0.0 — 2023-09-10
- 3.1.0 — 2023-01-26
- 3.0.4 — 2021-07-20
- 3.0.3 — 2021-07-20
- 3.0.2 — 2021-05-17
- 3.0.1 — 2021-05-17
- 3.0.0 — 2021-01-29
- 2.0.3 — 2020-12-08
- 2.0.2 — 2019-11-29
- 2.0.1 — 2019-11-11
- 2.0.0 — 2019-11-06
- 1.1.0 — 2019-10-25
- … 3 more at https://npm.io/package/periscopic/versions

## README

# periscopic

Utility for analyzing scopes belonging to an ESTree-compliant AST.


## API

```js
import { analyze } from 'periscopic';

const ast = acorn.parse(`
const a = b;
console.log(a);
`, { ecmaVersion: 2022 });

const { map, globals, scope } = analyze(ast);
```

* `map` is a `WeakMap<Node, Scope>`, where the keys are the nodes of your AST that create a scope
* `globals` is a `Map<string, Node>` of all the identifiers that are referenced without being declared anywhere in the program (in this case, `b` and `console`)
* `scope` is the top-level `Scope` belonging to the program


### Scope

Each `Scope` instance has the following properties:

* `scope.block` — true if the scope is created by a block statement (i.e. `let`, `const` and `class` are contained to it), false otherwise
* `scope.parent` — the parent scope object
* `scope.declarations` — a `Map<string, Node>` of all the variables declared in this scope, the node value referes to the declaration statement
* `scope.initialised_declarations` — a `Set<string>` of all the variables declared and initialised in this scope
* `scope.references` — a `Set<string>` of all the names referenced in this scope (or child scopes)

It also has two methods:

* `scope.has(name)` — returns `true` if `name` is declared in this scope or an ancestor scope
* `scope.find_owner(name)` — returns the scope object in which `name` is declared (or `null` if it is not declared)


### `extract_identifiers` and `extract_names`

This package also exposes utilities for extracting the identifiers contained in a declaration or a function parameter:

```js
import { extract_identifiers, extract_names } from 'periscopic';

const ast = acorn.parse(`
const { a, b: [c, d] = e } = opts;
`, { ecmaVersion: 2022 });

const lhs = ast.body[0].declarations[0].id;

extract_identifiers(lhs);
/*
[
	{ type: 'Identifier', name: 'a', start: 9, end: 10 },
	{ type: 'Identifier', name: 'c', start: 16, end: 17 },
	{ type: 'Identifier', name: 'd', start: 19, end: 20 }
]
*/

extract_names(lhs);
/*
['a', 'c', 'd']
*/
```


## License

[MIT](LICENSE)

---
_Source: https://npm.io/package/periscopic · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
