Vibe coding can turn a plain-language request into a working demo surprisingly quickly. A working demo, however, is evidence that one path ran once. It is not evidence that the software is secure, accessible, maintainable, observable, or safe to change.

The useful way to work in 2026 is to keep the fast feedback loop while restoring the engineering controls that a prompt cannot replace. Define the problem before generating code. Make small changes that can be reversed. Inspect the diff. Test the behavior. Review security and accessibility. Deploy with monitoring and a rollback path.

Core rule: treat generated code as an untrusted draft. The person or team that ships it owns every line, dependency, migration, permission, and failure mode.

What vibe coding means

Andrej Karpathy introduced the phrase in a February 2025 post about building a throwaway weekend project through conversation with a coding model. His description was deliberately hands-off: accept changes, run the result, feed errors back, and avoid thinking much about the underlying code.

The phrase is now often used more broadly for any development led by natural-language instructions. That broader usage hides an important distinction. Pure vibe coding optimizes for visible progress while allowing understanding to lag behind. AI-assisted engineering may use the same tools, but requirements, architecture, review, verification, and operational ownership remain explicit.

Both approaches can produce a prototype. Only the second is a sensible route toward software that other people will depend on.

Choose the risk level before you start

Do not decide whether a project is safe by looking at how polished the interface appears. Decide from its data, users, permissions, and consequences. A local mockup with invented data has a very different risk profile from a service that handles identities, payments, health information, or irreversible actions.

Low-risk prototypes and high-control systems
Reasonable starting pointNeeds experienced engineering and formal controls
Disposable interface explorationAuthentication, authorization, account recovery, or payments
A local script using non-sensitive test dataPersonal, confidential, regulated, or production data
A proof of concept that can be deletedSafety-critical or high-availability systems
Scaffolding behind an existing test suiteDatabase migrations, destructive operations, or production infrastructure
An isolated internal experiment with a named ownerPublic software that no one on the team can debug or support

A prototype can graduate, but graduation is a separate decision. Reassess the design when real users, real data, money, external integrations, or operational commitments enter the picture. Do not let a successful demo silently become a production system.

Write the contract before the prompt

A model cannot reliably infer requirements that the team has not decided. Before asking for code, write a short build contract that a reviewer could understand without reading the chat history.

  • Outcome: who needs what capability, and why?
  • Acceptance: which examples must work, and which edge cases must fail safely?
  • Non-goals: what is deliberately outside this change?
  • Data: what enters, where it is stored, how long it remains, and who may access it?
  • Trust boundaries: where does untrusted input cross into the application, database, filesystem, or external service?
  • Constraints: supported platforms, performance limits, accessibility target, approved dependencies, and licensing policy.
  • Operations: who owns the feature, how it is monitored, and how it can be disabled or rolled back?

Then sketch the architecture. Name the components, interfaces, state transitions, and failure behavior. Mark the invariants that must not change, such as tenant isolation, authorization checks, idempotency, or a public API contract. Ask the model to critique the plan before asking it to edit files. A plausible plan is still a proposal, so resolve uncertain decisions with the people who own the system.

The NIST Secure Software Development Framework groups its high-level practices around preparing the organization, protecting software, producing well-secured releases, and responding to residual vulnerabilities. It is a useful structure for ownership across the lifecycle, not a claim that one tool or checklist makes a release secure.

A useful change request: state the outcome, affected files, constraints, acceptance checks, commands to run, files that must not change, and the expected diff size. Ask for a plan first. Require the agent to stop when it encounters an unknown dependency, permission, migration, or destructive action.

Create a reversible baseline

Put the project in version control before generation begins. Confirm that the current build and tests pass, then create a branch or equivalent isolated workspace. Commit a clean baseline. This separates pre-existing problems from defects introduced by the generated change.

Keep production credentials out of the environment. Use synthetic or sanitized data. Restrict filesystem, network, shell, cloud, and repository permissions to what the task needs. If the agent can run commands or use tools, review that tool scope as carefully as an application permission.

For repositories hosted on GitHub, protected branches can require reviews and status checks before merge, as described in GitHub's branch protection documentation. Other platforms have comparable controls. The important design is independent approval and a recorded change, not a particular vendor.

Work in small, explainable diffs

Ask for one behavior at a time. A small diff is easier to inspect, test, revert, and compare with the requirement. It also limits the damage from a wrong assumption. Avoid prompts such as "finish the app" or "fix everything" when the agent can modify a large repository.

After each change:

  1. read the diff, including configuration, generated files, lockfiles, and deleted tests;
  2. ask what assumptions were made and which edge cases remain;
  3. run the narrowest relevant checks;
  4. exercise the changed behavior yourself;
  5. commit only when the change is coherent and reversible.

If you cannot explain the new behavior, do not stack another prompt on top. Reduce the change, add a characterization test, or bring in someone who understands the affected area. Repeated prompting can make a symptom disappear while leaving the underlying defect in place.

Verify dependencies, code origin, and licenses

Generated suggestions can name packages that do not exist, select obsolete versions, or add a library where a few lines of local code would be clearer. A package is executable supply-chain code, not a convenient sentence in a response.

For every added or updated dependency, verify the exact package and publisher in the authoritative registry. Inspect release history, maintenance status, transitive dependencies, known vulnerabilities, and license compatibility. Pin versions according to the ecosystem's normal practice and commit the lockfile. Remove unused packages after the change.

OWASP's dependency management guidance recommends bringing automated dependency analysis in early rather than waiting until the end. GitHub's official guide to reviewing AI-generated code also calls out fabricated APIs, deleted or skipped tests, suspicious packages, and incompatible licenses as specific review concerns.

Apply the same scrutiny to copied snippets. Record where externally derived code came from and whether its license permits the intended use. A model's output does not erase intellectual-property obligations.

Protect secrets, data, and build paths

Do not paste credentials, customer records, private keys, proprietary source, or production logs into a prompt unless the organization has explicitly approved that data flow. Check what files and terminal output the tool can include as context. A .gitignore file controls what Git tracks; it does not prevent an agent from reading a file on disk.

Use a secrets manager or an approved CI secret store, issue short-lived credentials where possible, and scope each identity to the minimum required access. OWASP's secrets management guidance covers central storage, access control, rotation, logging, and incident response.

Review changes to package scripts, CI workflows, containers, deployment manifests, and infrastructure code with extra care. These files can execute in trusted environments. OWASP's current Secure Coding with AI guidance warns against giving agents production credentials, treating passing generated tests as security evidence, or allowing unreviewed changes to build and deployment paths.

Build independent evidence

A green screen in the preview is the start of verification, not the end. Create checks from the written requirements, not from the generated implementation alone. Otherwise the same mistaken assumption can appear in both code and tests.

  • Functional: unit tests for important logic, integration tests at boundaries, and end-to-end tests for critical user journeys.
  • Failure: invalid input, timeouts, duplicate requests, partial writes, empty states, missing permissions, unavailable services, and recovery.
  • Static: compiler or type checks, linting, formatting, static application security testing, and dependency scanning.
  • Security: authentication and authorization, input validation, output encoding, data exposure, rate limits, business logic, and abuse cases.
  • Accessibility: keyboard use, focus order, labels, errors, zoom and reflow, contrast, reduced motion, and assistive-technology checks relevant to the interface.
  • Operational: migration rehearsal, backup restore, load behavior, alerts, and rollback.

Automated checks cover only part of the surface. OWASP's secure code review guide highlights business logic, authorization, trust boundaries, and other context-dependent issues where human review matters. The W3C states that WCAG 2.2 is designed to be tested with a combination of automation and human evaluation.

Review for ownership, not just syntax

The reviewer should be able to trace each acceptance criterion to code and evidence. Review the whole diff, not only the files the agent summarizes. Ask whether the change fits the architecture, duplicates existing behavior, widens permissions, changes data retention, breaks compatibility, or creates an operational obligation.

Security-sensitive code deserves a reviewer with relevant expertise. The authoring agent should not be the only reviewer, and a second model is not independent accountability. Record the human decision, unresolved risks, and any follow-up work.

Documentation is part of the feature. Update the setup guide, configuration reference, data model, API contract, architecture decision, support runbook, and ownership entry as applicable. If the only explanation lives in a chat session, the team does not yet own the change.

Deploy with observation and rollback

Separate deployment from release when possible. Ship to a non-production environment first. Use a staged rollout, limited audience, or feature flag for changes with meaningful risk. Define the success signal and the rollback trigger before release.

Instrument the behavior that users and operators care about. That usually includes structured logs, service and business metrics, traces across important boundaries, health checks, and alerts tied to an actionable threshold. The OpenTelemetry observability primer provides a vendor-neutral introduction to logs, metrics, and traces. Redact sensitive data and test that telemetry is useful during failure, not only during a successful request.

Write a rollback plan that names the command, owner, data consequence, and verification step. Database changes need special care: prefer backward-compatible migrations, rehearse them on representative data, take tested backups, and know whether application rollback is possible after the schema changes. A rollback document that has never been exercised is only a hypothesis.

Production-readiness checklist

Use this as a release conversation, not as a compliance certificate. The required depth depends on the system's risk.

Product and architecture

  • The user outcome, non-goals, edge cases, and acceptance checks are written.
  • Data flows, trust boundaries, permissions, failure states, and integrations are understood.
  • A named owner can explain and support the implementation.

Code and supply chain

  • The full diff is reviewed; unexplained code and unrelated changes are removed.
  • Dependencies exist, are maintained, are vulnerability-checked, and have compatible licenses.
  • Secrets are outside the repository and agent context; credentials are scoped and rotatable.
  • Build, CI, container, and deployment changes received explicit review.

Verification and accessibility

  • Tests derive from requirements and include failure paths, not only generated happy paths.
  • Compile, type, lint, static security, dependency, and relevant dynamic checks pass.
  • Authentication, authorization, validation, privacy, and abuse cases have human review.
  • Keyboard, focus, labels, errors, contrast, zoom, reflow, and relevant assistive technology are tested.

Operations and release

  • Configuration, migrations, backups, restore, and environment differences are tested.
  • Logs, metrics, traces, alerts, and runbooks cover the new failure modes.
  • The rollout is bounded, and rollback has an owner, trigger, procedure, and verification step.
  • Documentation and support ownership will remain after the chat session is gone.

Keep the speed, own the software

Vibe coding is most useful when it lowers the cost of exploring an idea. It becomes dangerous when visible progress is mistaken for production readiness. The transition point is simple: once other people, sensitive data, money, or continuing operations depend on the result, stop forgetting that the code exists.

Use natural language to accelerate implementation, but keep the hard decisions visible. Requirements, architecture, small diffs, version control, dependency review, secret handling, independent tests, accessibility, security, human review, observability, and rollback are not ceremony added after the creative work. They are how a prototype becomes software a team can responsibly own.