Skip to content

Latest commit

 

History

History
207 lines (131 loc) · 11.9 KB

File metadata and controls

207 lines (131 loc) · 11.9 KB

Development

Build instructions and development setup for contributing to Graph Explorer. For system design and key libraries, see Architecture.

Requirements

  • pnpm 12.4.2, pinned by packageManager
  • node >=24.21.0

Node Version

Ensure you are running the correct Node version. If you are using NVM, you can simply do:

nvm use

Otherwise, use whatever method you use to install Node v24.21.0.

pnpm version

packageManager in the root package.json pins the exact pnpm version, and you do not have to match it yourself. Any pnpm 11 or newer reads that field and hands the command to the pinned version, so install pnpm however you like and let it switch:

brew install pnpm            # or: npm install -g pnpm
pnpm --version               # prints the pinned version, not the one you installed

The standalone script works too. Prefer any of these over Corepack, because letting pnpm switch versions itself brings the pinned version in as a normal package install, whose integrity the lockfile records for every platform.

If you have Node but no pnpm at all, Corepack ships with Node 24 and can bootstrap it for you:

corepack enable

Corepack takes a different path to the same version, in two hops. It downloads the pnpm package and checks it against the hash in packageManager, the same hash this repo pins. pnpm 12 is a native executable though, and Corepack installs no dependencies, so pnpm then fetches its own platform binary on first use. That second download is checked against npm's registry signature rather than against the pinned hash. Never set COREPACK_INTEGRITY_KEYS to 0 or empty to work around a failed download, because that turns the signature check off entirely.

Upgrading pnpm

Three files carry the pnpm version itself:

  • packageManager in package.json, which is what self-managing pnpm, Corepack, and CI all resolve.
  • pnpm-lock.yaml, which records the version under packageManagerDependencies plus an integrity for pnpm and for each @pnpm/exe.* platform package. corepack use regenerates this; never hand-edit it. Editing packageManager by hand still runs the version you typed, and rewrites these entries to match it, even under --frozen-lockfile. So the lockfile does not go stale, but the change lands in a commit nobody reviewed as a lockfile change.
  • The pnpm requirement at the top of this document.

Two more pin a different tool whose version is tied to the pnpm major, so they stay put on a patch or minor bump and move only when the major changes:

  • corepack@<version> in the Dockerfile. The container gets pnpm only through corepack enable, and pnpm 12 ships as a native executable, so a new pnpm major needs a Corepack release that can fetch and verify that binary. A Corepack release's notes name the pnpm majors it handles.
  • pnpm/action-setup in .github/workflows/unit.yml, covered below.

Run corepack use pnpm@<version> from the repo root. It rewrites packageManager with a freshly computed integrity hash and then runs pnpm install, which updates the lockfile. Do not hand-write the hash. If corepack is not on your PATH, install it with npm install -g corepack@<version>; Node 24 bundles Corepack but only behind corepack enable, and later Node lines drop it entirely.

On a major bump, raise the Dockerfile's Corepack pin before running corepack use, because the Corepack currently pinned is by definition the one that predates the new pnpm major. Nothing in the commands below builds the image, so a Corepack pin too old to fetch the new pnpm surfaces only when test_build_docker.yml runs on the pull request. Run docker build . locally if you would rather find out sooner.

Do not reach for pnpm self-update. It rewrites packageManager without the +sha512 hash, throwing the integrity pin away. corepack use is the only command that writes a correct pin.

Update this document to the same version, then confirm nothing shifted:

pnpm install --frozen-lockfile
pnpm checks
pnpm test

.github/workflows/unit.yml reads the version from packageManager, so a patch or minor bump needs no workflow edit. A major bump usually does. pnpm/action-setup bootstraps pnpm from lockfiles committed inside the action itself, so it needs a release that knows about the new major. v6.1.0 is the release that added pnpm 12. On a major bump, update the pinned commit SHA and its version comment in the workflow.

No check compares the +sha512 hash against anything, because the two tools that install pnpm already verify the bytes they fetch and both fail closed. Corepack reads the hash and refuses a wrapper that does not match it. pnpm ignores the hash and instead checks each download against the integrity in pnpm-lock.yaml and against npm's registry signature, so a tampered lockfile stops the install with "its npm registry signature could not be verified" rather than passing quietly.

A major bump is also where pnpm-workspace.yaml deserves a read. Since pnpm 12, a key that pnpm does not recognize fails the install with ERR_PNPM_UNRECOGNIZED_WORKSPACE_SETTINGS instead of being ignored. So a setting removed or renamed upstream stops the install rather than quietly doing nothing. pnpm config list prints the pnpm-workspace.yaml settings pnpm resolved, which is the quickest way to check, though it lists neither pnpm's defaults nor anything from .npmrc.

Run in development mode

Install any missing or updated dependencies.

pnpm install

Start the development servers.

pnpm dev

Launch your web browser of choice and navigate to

http://localhost:5173

At this point, Graph Explorer should be successfully running and it is asking you for connection details. This part is specific to your personal setup.

Build for production

pnpm install
pnpm build

This builds the React client into static assets at packages/graph-explorer/dist/. The proxy server has no build step — Node runs its TypeScript source directly using native type stripping.

Start the proxy server, which also serves the built client assets:

pnpm start

Build and run with Docker

You can also build and run Graph Explorer as a Docker image from source.

docker build -t graph-explorer .

Run the container with HTTPS disabled for local use:

docker run -p 80:80 \
  --name graph-explorer \
  --env PROXY_SERVER_HTTPS_CONNECTION=false \
  --env GRAPH_EXP_HTTPS_CONNECTION=false \
  graph-explorer

Then open http://localhost/explorer in your browser.

Managing dependencies

If you need to add, remove, or update a dependency you can easily do so from the root folder in the CLI:

# Adding a package for the react app
pnpm add react --filter graph-explorer

# Adding a dev only dependency for the server app
pnpm add -D vitest --filter graph-explorer-proxy-server

Preparation of a release

This repository is composed of 3 packages and a mono-repository structure itself. Then, you need to take into account 4 different package.json files:

  • <root>/package.json is intended to keep the dependencies for managing the repository. It has utilities like linter, code formatter, or git checks.
  • <root>/packages/graph-explorer/package.json is the package file that describes the UI client package.
  • <root>/packages/graph-explorer-proxy-server/package.json is the package file for the node server which is in charge of authentication and redirection of requests.
  • <root>/packages/shared/package.json is the package file for shared code between the client and server packages.

Each of these package.json files has an independent version property. However, in this project we should keep them correlated. Therefore, when a new release version is being prepared, the version number should be increased in all 4 files. Regarding the version number displayed in the user interface, it is specifically extracted from the <root>/packages/graph-explorer/package.json file.

Supply chain security

The pnpm-workspace.yaml file includes several settings that harden the project against supply chain attacks. These may cause pnpm install to fail when adding new dependencies, which is intentional.

  • minimumReleaseAge — Newly published package versions are blocked for 24 hours, giving the community time to discover and report compromised releases.
  • allowBuilds — A map giving each dependency that wants to run a build script (e.g. postinstall) an explicit true or false. Anything absent from the map fails the install, because pnpm's own strictDepBuilds is on by default.
  • blockExoticSubdeps — Transitive dependencies cannot resolve to git repositories or raw tarball URLs. Only direct dependencies in package.json may use exotic sources.
  • trustPolicy — Refuses to install a package version whose publish-time trust evidence (provenance, signatures) is weaker than a previously published version of that package.

If pnpm install fails due to one of these checks, evaluate whether the dependency is safe and update pnpm-workspace.yaml accordingly.

Local environment overrides

Create a .env.local file in packages/graph-explorer/ to override environment variables without modifying tracked files. This file is gitignored and will not be committed.

Example packages/graph-explorer/.env.local:

GRAPH_EXP_DEV_PORT=5174
PROXY_SERVER_HTTP_PORT=8082

Environment variables

See the Configuration Reference for all available environment variables including application settings and default connection options.

Development-only environment variables

These variables only affect the local development server (pnpm dev) and have no effect on production builds or Docker.

GRAPH_EXP_DEV_PORT

Sets a fixed port for the Vite development server. When set, strictPort is enabled — Vite will fail with an error if the port is already in use rather than silently selecting another port. This ensures the dev server runs on the exact port you intend.

Example: 5174

  • Optional
  • Default: Vite's default behavior (auto-selects an available port starting at 5173)
  • Type: number

Using self-signed certificates with Docker

  • Self-signed certificates will use the hostname provided in the docker run command, so unless you have specific requirements, there are no extra steps here besides providing the hostname.
  • If you would like to modify the certificate files, be aware that the Dockerfile will make automatic modifications on run in the entrypoint script, so you will need to remove these lines.
  • If you only serve one of either the proxy server or Graph Explorer UI over an HTTPS connection and wish to download from the browser, you should navigate to the one served over HTTPS to download the certificate.
  • The other certificate files can also be found at /packages/graph-explorer-proxy-server/cert-info/ on the Docker container that is created.

Using self-signed certificates on Chrome

See Removing the "Not Secure" warning on Chrome in the security reference.

Troubleshooting

  • If you need more detailed logs, you can change the log level from info in the default .env file to debug. The logs will begin printing the error's stack trace.
  • If Graph Explorer crashes, you can recreate the container or run pnpm start
  • If Graph Explorer fails to start, check that the provided endpoint is properly spelled and that you have access to from the environment you are trying to run in. If you are in a different VPC, consider VPC Peering.