
Claude Code Hooks (2026): Complete Setup Guide, Examples & Troubleshooting
Quick Answer
Claude Code can read files, modify code, run terminal commands, and interact with development tools. But what if you need certain actions to happen automatically whenever Claude edits a file, requests permission, or reaches a particular stage of its workflow?
That's where Claude Code hooks come in.
Hooks allow developers to automate repeatable actions such as formatting source files, checking protected paths, displaying notifications, and running validation scripts. Unlike ordinary instructions, hooks are tied to specific Claude Code lifecycle events.
This guide explains how to configure Claude Code hooks in 2026, where to save their settings, how different events work, and how to create practical automations with JSON and Python examples.
What Are Claude Code Hooks and How Do They Work?
Claude Code hooks are configurable handlers that run when specified lifecycle events occur, such as before a tool call, after a file edit, or when a session starts. Developers define them in Claude Code settings to trigger commands, HTTP requests, MCP tools, or model-assisted checks for automation, validation, notifications, and workflow control.
Why Developers Use Claude Code Hooks
AI coding assistants can follow project instructions, but some tasks should not depend on whether the assistant remembers to perform them.
For example, a developer may want code formatting to run after every supported file edit, a warning to appear when Claude attempts to change a protected configuration file, or a desktop notification when permission is required.
Claude Code hooks make these workflows event-driven.
A hook runs because a defined event occurs—not simply because an instruction asks Claude to remember something.
Common Claude Code hook use cases
Use case | Relevant event | Example action |
|---|---|---|
Format code after editing |
| Run Prettier after an Edit or Write operation |
Check a protected file before modifying it |
| Inspect the target path and reject certain edits |
Notify the developer |
| Display a desktop notification |
Load project context |
| Add development conventions to the session |
Check a submitted prompt |
| Validate or augment the submitted request |
Record failed tool operations |
| Send a failure record to a logging system |
Respond when Claude finishes |
| Trigger a task-end notification or validation |
Save information before compaction |
| Preserve relevant context through a supported process |
Important: A PostToolUse hook executes after the relevant tool has already run. It can report or correct some results, but it cannot retroactively prevent the original action.
To block a supported tool call before execution, use PreToolUse.
Claude Code Hooks vs. CLAUDE.md vs. Skills vs. MCP
Developers often confuse Claude Code hooks with other extension features.
These tools solve different problems and can work together.
Feature | What it does | When to use it |
|---|---|---|
Hooks | Respond to lifecycle events through configured handlers | Enforce checks, automate formatting, trigger notifications |
CLAUDE.md | Provides persistent instructions and project context | Coding conventions, architecture notes, repository guidance |
Skills | Supplies reusable, task-specific instructions and workflows | Code reviews, documentation, testing playbooks |
MCP servers | Connects Claude to external tools and data sources | Repositories, databases, APIs, developer services |
Subagents | Perform delegated work with separate contexts | Focused research, code analysis, specialized tasks |
Example: Using all four together
Consider a SaaS team building a Next.js marketing website.
Its CLAUDE.md file explains the coding conventions.
A development skill describes how to review a pull request.
An MCP server gives Claude access to an approved external service.
A PostToolUse hook checks or formats a file after a supported edit.
These components are complementary. A hook does not replace a skill, and adding an MCP server does not automatically create a hook.
Practical rule: Use a hook when the same action should be triggered by a specific event. Use instructions or skills when the task requires flexible reasoning.
How Claude Code Hooks Work: Event, Matcher, Handler
A standard Claude Code hook configuration has three main parts:
Event: When the automation should run.
Matcher: Which events or tools should activate it.
Handler: What command, endpoint, tool, or model-assisted check should execute.
Here is a basic configuration shape:
In this example:
PostToolUseidentifies the lifecycle event.Edit|Writematches either the Edit or Write tool.type: "command"selects a command handler.commanddefines the command that runs after a matching successful tool call.
The event occurs first. Claude Code evaluates the matcher, then executes the matching handler.
The command output from this simple example is primarily useful for debugging. It is not intended to change Claude's response or modify a file.
Step 1: Choose the Correct Claude Code Hooks Settings File
Claude Code reads hook configurations from several settings locations.
Choosing the right file determines whether a hook applies to every project or only one repository.
Claude Code hook configuration locations
Settings location | Scope | Recommended use |
|---|---|---|
| Personal, across local projects | Personal notifications and preferences |
| Shared project configuration | Team formatting and repository checks |
| Personal configuration for one project | Testing a hook before sharing it |
Managed settings | Organization-controlled | Administrative policies |
Plugin hook configuration | When the plugin is active | Reusable packaged automation |
For a developer working on multiple projects, personal notifications usually belong in the home-directory settings file.
For repository-specific validation, the shared project settings file is a more appropriate choice when the team agrees to the behavior.
Example project structure
The settings.json file contains hook registrations.
The hooks directory contains any supporting scripts.
What if settings.json does not exist?
Create the .claude directory and the appropriate settings file.
For macOS or Linux, you can create the project directory from the project root:
Then create .claude/settings.json with a text editor.
If the file already exists, merge the new event configuration into its existing hooks object. Do not replace unrelated settings, permissions, or hooks.
Use valid JSON with no trailing commas or comments.
Step 2: Create Your First Claude Code Hook
A notification is a useful beginner example because it does not need to modify your source files.
The example below uses the Notification lifecycle event.
Example A: Desktop notification on macOS
Add this configuration to ~/.claude/settings.json:
The empty matcher allows the handler to run for all notification types.
What happens next?
When Claude Code emits a notification event, the configured command asks macOS to display a desktop notification.
This does not mean a notification appears after every file edit. It runs for notification events, which can include permission requests or idle prompts.
How to verify the hook
Save the settings file.
Open Claude Code in your terminal.
Type
/hooks.Locate the
Notificationevent and confirm the handler appears.Trigger an operation that requires your attention.
Check whether the desktop notification appears.
macOS may require notification permissions for the application responsible for displaying the message.
Linux and Windows alternatives
On supported Linux desktop environments, a notification command can use:
This requires an appropriate notification daemon and notify-send to be available.
On Windows, a hook can use PowerShell. Claude Code supports selecting PowerShell explicitly through the handler's shell field.
This Windows example writes a message through PowerShell rather than displaying a desktop toast. A native popup requires an appropriate notification implementation.
Testing note: Notification behavior depends on operating-system permissions and whether the development session has access to a graphical desktop.
Step 3: Understand the Most Useful Claude Code Hook Events
Claude Code supports numerous lifecycle events, and the official event list can expand as the product changes.
Rather than memorizing a fixed event count, understand the events relevant to your workflow.
Common lifecycle event reference
Event | When it runs | Can it block the original operation? |
|---|---|---|
| When a session starts or resumes | No |
| When the user submits a prompt | Yes |
| Before a supported tool call runs | Yes |
| When Claude Code needs a permission decision | Can allow or deny through its decision schema |
| After a tool succeeds | Cannot undo the completed action |
| After a tool fails | No |
| When Claude Code emits a notification | No |
| When a subagent starts | No |
| When a subagent finishes | Can prevent the subagent from stopping |
| When Claude finishes responding | Can request continued work |
| Before conversation compaction | Yes |
| When the session ends | No |
This is a selected reference, not a complete list of every supported event.
PreToolUse vs. PostToolUse
The difference matters when implementing safeguards.
PreToolUse example: Claude is about to edit a protected configuration file. A hook inspects the requested operation and rejects it before the Edit or Write tool executes.
PostToolUse example: Claude finishes editing a JavaScript file. A hook runs a local formatter on the resulting file.
Use a pre-execution check for preventive controls and a post-execution hook for follow-up work.
What about Stop hooks?
A Stop hook runs when Claude finishes a response, not necessarily when an entire multi-step software project is fully complete.
Be careful when blocking a stop event. An incorrect condition can cause unnecessary continuation attempts.
For beginners, Notification, PostToolUse, and narrowly scoped PreToolUse hooks are easier starting points.
Step 4: Configure Matchers Correctly
The matcher controls which events trigger a handler.
For tool-related events, common matcher values include:
Matcher | Intended behavior | |
|---|---|---|
| Match the Bash tool | |
| Match the Edit tool | |
| Match the Write tool | |
`Edit | Write` | Match either Edit or Write |
| Match every supported value for the event | |
| Regular-expression match for MCP tool names |
Matchers are case-sensitive.
For example, Edit|Write is not the same as edit|write.
How MCP tool names work
MCP tools generally have names following a pattern similar to:
mcp__server_name__tool_name
A matcher using mcp__.* can target MCP tools broadly.
However, broad matchers can trigger more often than intended, and some plugin-provided MCP tools use additional name prefixes.
For sensitive automation, match the specific tool or server you intend to handle.
Avoid expensive hooks on every tool call
A command that performs network requests or runs a large test suite after every tool operation can noticeably slow development.
Use matchers to restrict unnecessary execution.
Where available and appropriate, additional if conditions can filter commands or file operations more narrowly.
Step 5: Understand the JSON Data Passed to Hooks
Command hooks receive event information as JSON through standard input (stdin).
The fields available depend on the event.
For a file-editing tool, a simplified input might resemble:
This is a simplified illustrative payload, not a captured live session. Real tool inputs may contain additional fields.
Your hook script can read the JSON, inspect the tool name or file path, and return an appropriate result.
Command hook exit codes
Exit code | General meaning | Practical implication |
|---|---|---|
| Command completed successfully | Continue normally; valid JSON output may provide additional decisions |
| Special blocking or feedback signal | A |
Other nonzero code | Failure | Usually reports a hook error; behavior depends on event and failure configuration |
Do not assume exit code 2 blocks every event.
For example, PostToolUse runs after the action, so the original edit cannot be prevented.
PermissionRequest has its own structured decision format and does not use exit code 2 as a generic permission denial.
Structured JSON decisions
A PreToolUse hook can explicitly deny a tool call through structured output:
When returning structured JSON from a command hook, exit successfully and print a valid JSON object without unrelated text on stdout.
An invalid JSON response may be ignored or treated as an error depending on the event and failure settings.
Step 6: Example — Protect Sensitive Project Files with PreToolUse
A useful safety workflow is preventing Claude's Edit and Write tools from modifying selected configuration files.
For example, you may want to restrict edits to:
.envand.env.*files.package-lock.json.Files inside
.git/.Paths outside the intended project directory.
Important limitation: The example below checks the target path of the Edit and Write tools. It is not a complete security sandbox and does not intercept every possible file modification through other tools or shell commands.
A. Create the protection script
Save this file at:
.claude/hooks/protect_files.py
This script reads the attempted target path, resolves it against the project directory, and blocks paths outside the project or within the selected protected patterns.
It uses Python's path handling rather than simply searching for a dangerous substring anywhere in a filename.
B. Register the PreToolUse hook
For macOS, Linux, or a compatible Unix-like shell environment, add this to .claude/settings.json:
Ensure that Python 3 is available.
The onFailure setting requests blocking behavior if the handler fails unexpectedly, rather than allowing an edit simply because the guard script could not execute.
For native Windows configurations, adapt the command using the PowerShell or executable invocation supported by your Claude Code installation.
C. Test the protection logic
From the project root, you can send an illustrative event to the script:
Expected result:
Repeat using a normal source path such as src/app.ts. The script should exit successfully without printing a blocking message.
D. Important test results
The Python path-checking logic in this example was checked locally with simulated inputs for a normal source file, .env.local, .git/config, and a path outside the project.
Those checks produced the intended allow/block exit codes.
This is not an end-to-end Claude Code integration test. You should still confirm the handler's behavior in your installed Claude Code version, especially before applying it to a shared repository.
Step 7: Example — Automatically Format Code After Claude Edits a File
One popular Claude Code hook workflow is running a formatter after supported code edits.
For a JavaScript or TypeScript project, Prettier is a common choice.
The official Claude Code Hooks Guide provides a compact example using jq to extract the edited file path and run Prettier.
For projects that need stricter file-path handling, a separate script is preferable.
Prerequisites
Your project needs Node.js and a locally installed Prettier package.
Install Prettier using your project's package manager and standard dependency-management policy.
For an npm-based project, the development dependency command is:
A. Create the formatting script
Save as:
.claude/hooks/format_file.py
B. Register the formatting hook
Add this event to the project's existing hooks object:
Configuration reminder: If you already added the PreToolUse example, place PostToolUse alongside it inside the same top-level hooks object. Do not create a second JSON object or overwrite your other settings.
C. What happens during a file edit?
Claude successfully edits or writes a file.
Claude Code emits a matching
PostToolUseevent.The Python script reads the edited path.
The script confirms that the file belongs to the project and has an allowed extension.
The locally installed Prettier executable formats the file.
The developer can inspect the formatted file and the debug log.
This script deliberately does not install Prettier automatically or execute an arbitrary command supplied through hook input.
D. Limits of this approach
A PostToolUse hook only responds to matching tool events.
If another process changes a file outside those tool calls, this hook might not execute.
Claude Code also supports FileChanged hooks for certain file-system-triggered workflows.
The Python formatter example is provided as a configuration pattern. It has not been verified against a live Claude Code session in this article; validate it in a disposable test repository before treating it as production automation.
Step 8: Example — Add Context Automatically at Session Start
Not all hooks need to execute a formatter or block a tool.
Some can add useful project context when a session begins.
For example, a team may want Claude to remember a temporary migration freeze or development rule.
Add this to your project settings:
For SessionStart, suitable plain-text stdout can be added to Claude's context.
This differs from a typical PostToolUse command, where ordinary stdout is not automatically displayed as new user-facing content.
When should you use this?
Useful examples include:
Reminding the agent about a temporary deployment freeze.
Supplying environment-specific development context.
Referencing an approved workflow for the current repository.
Restoring selected context after compaction using the appropriate session-start matcher.
For permanent project-wide instructions, CLAUDE.md is generally a simpler primary location.
Use a hook when the instruction must be supplied at a particular lifecycle event or generated dynamically.
Step 9: Command, HTTP, MCP Tool, Prompt and Agent Hooks
Modern Claude Code supports multiple handler types.
They are not interchangeable.
Handler type | How it works | Typical use |
|---|---|---|
| Executes a local command or script | Formatting, validation, notifications |
| Sends event information to an HTTP endpoint | Internal monitoring and external automation |
| Invokes a configured MCP tool | Integrations with approved services |
| Uses a Claude model to evaluate a condition | Decisions requiring contextual judgment |
| Uses a subagent for more involved checks | Complex verification using tools |
Command hooks
Best for local actions that can be expressed as deterministic scripts.
They are appropriate for simple file checks, formatters, and environment inspection.
HTTP hooks
An HTTP handler sends hook information to an endpoint.
This can be useful for internal systems, but sending full event payloads to outside services may expose sensitive information.
Review what data is transmitted and use the documented authentication and allowlist options.
MCP tool hooks
MCP integrations can expose tools that run when particular lifecycle events occur.
Use the correct configured server and tool name. Avoid broad permissions simply to make an integration work.
Prompt-based hooks
These use a model to make decisions based on relevant context.
They are useful when a rule cannot be fully expressed with a simple deterministic check.
However, prompt-based decisions have model-related latency and are not equivalent to a guaranteed security control.
Agent-based hooks
An agent handler can investigate more complex conditions.
For example, it might inspect a group of files to assess whether a change satisfies a project-specific requirement.
Anthropic currently describes agent hooks as experimental, so production-critical implementations should be reviewed carefully.
Recommended starting point: Learn command hooks first. Add other handler types only when they solve a specific requirement that local scripts cannot handle effectively.
Step 10: How to Test and Debug Claude Code Hooks
Hook debugging should follow a repeatable process.
Start by confirming that the configuration loads, then test the script independently, and finally verify its behavior during an actual Claude Code event.
Test 1: Check the hooks browser
Inside Claude Code, enter:
Confirm that the intended event and handler are visible.
If the event does not appear, check the settings file location, JSON syntax, and applicable workspace trust or managed-policy restrictions.
Test 2: Validate settings JSON
If you have Python installed, use:
A successful parse confirms the JSON syntax is valid.
It does not prove that the hook event names, handler fields, or shell commands are correct.
Test 3: Run the script with sample input
For a file-validation hook:
Check the exit code.
Try both allowed and blocked file paths.
Test 4: Enable debug logging
Launch a diagnostic Claude Code session using:
The debug log is written to Claude Code's session debug directory.
You can also specify a log file directly:
Inspect the log for hook execution, error messages, timeouts, and matcher behavior.
Common Claude Code hooks errors and fixes
Problem | Likely cause | What to check |
|---|---|---|
Hook never runs | Wrong event or matcher | Verify case-sensitive event and tool names |
| Wrong file location, invalid JSON or policy | Check settings scope and syntax |
Script reports command not found | Missing executable or incorrect PATH | Use an installed tool and valid path |
Hook works in terminal but not Claude Code | Different environment or input | Inspect debug log and event JSON |
Permission hook has no effect | Wrong decision schema | Check event-specific output requirements |
JSON response is ignored | Extra stdout or invalid structure | Emit a single valid JSON object |
File is modified before warning | Used | Move preventive validation before the tool call |
Windows shell errors | Bash-only syntax or missing Git Bash | Use supported PowerShell configuration |
Hook runs repeatedly | Broad matcher or recursive side effect | Narrow the matcher and examine process behavior |
Session becomes slow | Expensive hook runs too frequently | Reduce event scope and command workload |
Why JSON responses sometimes fail
Structured hook responses must follow the correct schema for the event.
For example, a PreToolUse permission decision belongs in hookSpecificOutput, while other events may use a different response shape.
Avoid mixing diagnostic messages with structured JSON on stdout.
Put diagnostics in a suitable log or stderr, and use a JSON encoder rather than manually concatenating unescaped values.
Step 11: Claude Code Hooks Security Best Practices
Hooks can execute commands with the permissions of the user running Claude Code.
That makes them powerful, but also potentially dangerous.
Use these safeguards
Validate untrusted input. Never assume a file path or command string received from a hook event is safe.
Restrict sensitive paths. Avoid unnecessary access to credentials, environment files, private keys and repository internals.
Avoid unsafe shell interpolation. Use correctly quoted variables or argument arrays instead of inserting raw tool input into shell commands.
Use explicit project paths. Reference your intended project directory and reject paths that escape it.
Limit external data transmission. Review HTTP endpoints and any event payloads that may contain source code or project information.
Avoid broad auto-approval rules. A hook that approves every permission prompt can create much more risk than a narrowly scoped validation handler.
Review repository hooks before running unfamiliar projects. A shared .claude/settings.json file can contain executable hook registrations.
Test before sharing. Use a temporary or local project configuration until the behavior has been validated.
Do hooks replace a security sandbox?
No.
A file-protection hook that matches only Edit and Write calls does not automatically protect against all edits made through Bash commands, external processes, or integrations.
Critical access control belongs at the operating-system, repository, CI, or organizational policy level as appropriate.
A hook should complement these controls, not be presented as a complete security boundary.
Step 12: A Practical Hook Setup for a Web Development Team
Consider a small team building a Next.js SaaS website.
The team uses Claude Code to update React components, maintain content sections, and work on integrations.
A useful initial hook setup could include:
Workflow | Hook event | Intended result |
|---|---|---|
Protect selected configuration files |
| Reject targeted Edit and Write operations |
Format JavaScript and TypeScript |
| Apply Prettier after supported edits |
Show permission notifications |
| Alert a developer when attention is needed |
Add temporary project context |
| Remind Claude about current release requirements |
Record diagnostic failures |
| Capture relevant tool errors for review |
Recommended implementation order
Start with notifications because they are low-risk.
Then introduce a post-edit formatter in a test project.
After the formatter works, implement file-protection checks using a narrowly defined policy.
Only add model-assisted or external-service hooks when the business requirement justifies their complexity.
How to measure whether hooks help
Do not measure success by the number of hooks installed.
Instead, evaluate practical outcomes:
Fewer repetitive formatting corrections.
More consistent source-code conventions.
Reduced accidental edits to restricted files.
Faster awareness of permission prompts.
Clearer debugging records.
Less manual effort for repeatable tasks.
A team with three well-designed hooks may have a better workflow than a team with twenty overlapping automations.
For broader tools that support developer productivity, see our Best AI Coding Tools.
Claude Code Hooks Best Practices Checklist
Before moving a hook from a test environment into your regular workflow, confirm:
The hook solves a repeatable, clearly defined problem.
The event is appropriate for the action.
Matchers are as narrow as practical.
The settings file is at the correct scope.
Existing settings have been preserved.
The command or script is available in the intended environment.
Hook input is parsed safely.
File paths are validated when relevant.
Sensitive data isn't transmitted unnecessarily.
Return codes and structured responses use the correct event contract.
The hook has been tested with successful and failing examples.
The result has been verified during an actual Claude Code session.
Other developers understand the automation.
There is a documented way to disable or correct the hook.
A repository-level automation has undergone an appropriate security review.
Common Mistakes When Configuring Claude Code Hooks
Using the wrong hook event
A PostToolUse hook is suitable for formatting after an edit. It cannot prevent the edit that already occurred.
Use PreToolUse when a supported tool call must be checked before execution.
Replacing an existing settings file
Developers sometimes paste a complete example over their existing settings.json and accidentally remove other permissions or hook definitions.
Merge the relevant keys into the current configuration.
Using a wildcard for every event
Broad matchers can run commands unnecessarily, increase latency, and expose unrelated operations to an automation.
Start narrowly and expand only after testing.
Treating plain text as a structured JSON decision
Claude Code accepts event-specific decision objects. Printing an arbitrary message does not mean the action will be blocked.
Review the relevant output schema before implementing enforcement.
Ignoring operating-system differences
A Bash command written for macOS or Linux may not work in native Windows PowerShell.
Use a compatible interpreter and shell configuration.
Copying hooks from an unknown repository
Hooks may contain commands that can access or modify files.
Review the configuration and supporting scripts before trusting or executing unfamiliar projects.
Assuming hooks guarantee better AI-generated code
Hooks can improve workflow consistency and enforce certain checks, but they do not automatically establish code correctness, security, or maintainability.
Code review, testing, development standards, and appropriate permissions remain essential.
Are Claude Code Hooks Worth Using?
Claude Code hooks are most valuable when a developer has a repeated workflow that should run in response to a predictable event.
You may not need hooks when you are only experimenting with Claude Code or occasionally editing a file.
But as a project grows, carefully selected automations can help establish a more consistent development process.
Begin with a simple notification or formatting hook. Understand the event, matcher, command and output contract before implementing more restrictive controls.
For advanced workflows, evaluate HTTP, MCP-tool, prompt and agent handlers based on your actual requirements.
The goal is not to automate everything. It is to automate the repeatable work while retaining clear control over what executes, what changes, and how problems are detected.
Official Claude Code Documentation and References
These are the primary sources used for the technical guidance in this article:
The hook events, settings paths, matcher behavior, input/output rules, blocking behavior, and security guidance should be checked against the latest official reference whenever Claude Code changes.
Related reading: Before configuring automation, follow the Claude Code installation guide if the CLI is not yet ready.
For more automation options, compare the best AI automation tools and their use cases.
FAQs
What are hooks in Claude Code?
Claude Code hooks are event-driven handlers that execute when specific lifecycle events occur, such as before a tool call, after a successful edit, or when a session starts. Developers use hooks to automate formatting, validation, notifications, and other repeated workflows. Hooks can run commands, HTTP requests, MCP tools, or supported model-assisted checks.
How do I create a Claude Code hook?
Create or edit a Claude Code settings file, such as .claude/settings.json for a shared project or ~/.claude/settings.json for personal settings. Add a hooks object containing the event, optional matcher, and handler configuration. Save the file, use /hooks to verify that Claude Code recognizes the hook, and test the intended event.
What is the difference between PreToolUse and PostToolUse hooks?
PreToolUse runs before a supported tool call executes and can allow, deny, or request confirmation according to its decision schema. PostToolUse runs after a tool succeeds and is useful for formatting, logging, and follow-up checks. A PostToolUse hook cannot undo an action that has already occurred.
Can Claude Code hooks automatically format files?
Yes. A PostToolUse hook can match file-editing tools such as Edit and Write and run an installed formatter, including Prettier, against the affected file. The handler should validate file paths, limit the extensions it processes, and use a trusted local formatter. Test the configuration before enabling it for an important project.
Why are my Claude Code hooks not working?
Common causes include invalid JSON, a settings file in the wrong location, an incorrect or case-sensitive matcher, an unavailable executable, incompatible shell syntax, or restrictions from workspace trust and managed settings. Use /hooks to confirm configuration, test scripts independently with sample JSON, and inspect Claude Code debug logs for execution errors.
Author

Webflow & Framer Developer | Web Design & SEO Enthusiast
Shailesh Thakor is a Webflow and Framer developer specializing in modern, responsive websites and user-friendly digital experiences. His interests include website performance, technical SEO, AI-powered tools, and SaaS technologies. Through 8Spark, he shares practical insights into website builders, digital tools, and emerging technologies, with a focus on helping businesses and individuals make informed technology decisions.

