Agent Skills in Claude Code and Visual Studio Code: Setup, Benefits, Risks, and a Step-by-Step Example

Image
 AI coding assistants are useful for one-off questions, but many development tasks are not one-off tasks. A team may follow the same testing procedure before every release, use a specific format for code reviews, or require certain checks whenever a database migration is created. Repeating those requirements in every prompt is inefficient. Putting all of them into a permanent instruction file is not always ideal either, because the assistant may receive irrelevant information for tasks that do not need it. This is the problem that Agent Skills are designed to solve. A skill packages reusable instructions, supporting files, examples, and optional scripts into a folder. Claude Code or GitHub Copilot in Visual Studio Code can discover that folder and load its contents when the current task matches the skill’s purpose. Both environments support the open Agent Skills format, which makes it possible to share some skills across tools. This guide explains what skills are, how they differ ...

How to Test and Deploy Your First Vibe-Coded App


Reaching the point where an application appears to work on your computer is an important milestone.

It is not the same as being ready to publish.

A vibe-coded application may behave correctly during one successful demonstration while still containing broken edge cases, missing files, exposed development data, incorrect paths, or behavior that changes after deployment.

Testing and deployment should therefore be treated as separate stages.

Testing asks:

Does the application behave as intended under normal and unexpected conditions?

Deployment asks:

Can other people access the verified version in an environment outside my computer?

This article walks through a complete release process for the Personal Reading List Tracker. We will test its primary workflows, inspect the repository, prepare a release checkpoint, deploy it as a static website, verify the live version, and create a recovery plan.

Version note: Hosting dashboards, deployment settings, branch controls, and platform features can change. Verify current platform-specific instructions in the provider’s official documentation before publishing. The testing and release principles in this guide remain applicable across static hosting providers.

What You Will Learn

By the end of this guide, you should be able to:

  • define a release candidate;
  • stop feature development before testing;
  • create a practical manual test plan;
  • test normal, invalid, and edge-case behavior;
  • inspect browser console and network errors;
  • test local storage and optional API behavior;
  • review responsive layout and basic accessibility;
  • check the repository for secrets and development artifacts;
  • prepare a clean deployment commit;
  • deploy a static web application;
  • verify the live version after deployment;
  • recognize when a release should be rolled back.

Testing Comes Before Deployment

Deployment does not make an application correct.

It only moves the current version into another environment.

If the local version contains a bug, deployment usually publishes that bug.

A weak release process looks like:

The app seems to work
→ Push files
→ Publish
→ Discover problems later

A stronger process looks like:

Freeze the scope
→ Define the expected behavior
→ Test locally
→ Review the repository
→ Create a release checkpoint
→ Deploy
→ Test the live version
→ Monitor and record issues

The important difference is that deployment happens only after the application has passed a defined set of checks.

Define the Release Candidate

A release candidate is the exact version you are considering for publication.

It should not keep changing while you test it.

Suppose the reading list currently supports:

  • adding a book;
  • validating titles;
  • selecting a reading status;
  • rendering saved books;
  • filtering by status;
  • removing a book;
  • preserving data with local storage;
  • displaying empty and error states;
  • optionally searching an external book service.

These features form the release scope.

Once testing begins, avoid adding unrelated improvements such as:

  • new color themes;
  • editing;
  • sorting;
  • ratings;
  • cover animations;
  • account systems;
  • additional APIs.

Record those ideas separately.

A release candidate becomes difficult to verify when the code keeps changing during testing.

Confirm the Git State

Start with:

git status

Ideally, the result should show a clean working tree.

Then review recent history:

git log --oneline -8

You should recognize the commits that created the current application.

For example:

c731ae2 Improve empty and validation states
a96c503 Persist book additions and removals
4f2a0bc Filter books by reading status
2ac7e31 Add book removal
fd81b26 Validate book titles

If uncommitted changes exist, determine whether they are:

  • required for the release;
  • unfinished;
  • unrelated;
  • generated accidentally;
  • debugging leftovers.

Do not begin final testing from an unknown state.

Build a Test Plan from the Project Brief

Your test plan should come from the project brief and acceptance criteria.

The Personal Reading List Tracker has one main user workflow:

Enter book details
→ Select a status
→ Add the book
→ View it in the list
→ Filter or remove it
→ Refresh and keep the saved state

Testing should cover that workflow under several conditions.

A useful test plan includes:

  1. normal behavior;
  2. invalid input;
  3. empty states;
  4. data persistence;
  5. related feature interactions;
  6. responsive layout;
  7. failure behavior;
  8. deployment-specific behavior.

Do not test only the easiest successful path.

Step 1: Test the Initial Page State

Open the application with no saved reading-list data.

You may need to clear the site’s local storage in browser developer tools before beginning.

Expected behavior:

  • the page loads without a fatal error;
  • the heading is visible;
  • all form controls are present;
  • labels are understandable;
  • the title field is clearly required;
  • the author field is optional;
  • the status selector contains the supported statuses;
  • the Add Book button is available;
  • the empty-state message appears;
  • the filter control is visible;
  • no book cards appear.

Open the browser console.

There should be no unexpected JavaScript error.

A page that looks correct but reports an exception is not ready for release.

Step 2: Test Adding a Valid Book

Use a realistic example:

Title: Kindred
Author: Octavia E. Butler
Status: Finished

Expected behavior:

  • one book is added;
  • the title displays correctly;
  • the author displays correctly;
  • the selected status is visible;
  • the empty state disappears;
  • the title and author fields clear after successful submission;
  • the page does not reload unexpectedly;
  • only one book is created.

Now add a second book:

Title: The Dispossessed
Author: Ursula K. Le Guin
Status: Want to Read

Expected behavior:

  • both books remain visible;
  • their information does not become mixed;
  • the first book is not replaced;
  • status labels remain correct.

Check the Data Shape

If the application exposes state through development logs, remove those logs before release.

When inspecting local storage, each item should still follow the intended data model:

{
  "id": "unique-book-id",
  "title": "Kindred",
  "author": "Octavia E. Butler",
  "status": "finished",
  "createdAt": "2026-07-11T10:30:00.000Z"
}

Exact ID and timestamp values will vary.

The important point is that required fields remain consistent.

Step 3: Test Input Validation

Validation should prevent invalid data without damaging the current list.

Test an empty title.

Expected behavior:

  • no book is added;
  • a useful validation message appears;
  • existing books remain unchanged;
  • the status filter remains unchanged;
  • the form does not unexpectedly clear all fields.

Now test a whitespace-only title:

"     "

Expected behavior:

  • it is treated as empty;
  • no blank book card appears.

Test a title with surrounding spaces:

"   Parable of the Sower   "

Expected behavior:

  • the saved title becomes Parable of the Sower;
  • unnecessary surrounding spaces are removed.

Test an empty author.

Expected behavior:

  • the book can still be added;
  • the interface does not display undefined, null, or an empty label;
  • the title and status remain visible.

Test special characters where appropriate:

The Hitchhiker’s Guide to the Galaxy

The apostrophe should display correctly.

Avoid Arbitrary Stress Tests

You do not need to submit millions of characters to a beginner application.

Use realistic edge cases:

  • short title;
  • long but reasonable title;
  • punctuation;
  • accented characters;
  • blank author;
  • repeated title.

If the project brief does not prohibit duplicate books, do not invent that rule during release testing. Record duplicate handling as a future improvement if needed.

Step 4: Test Status Filtering

Add at least one book for each status:

Want to Read
Reading
Finished

Select All.

Expected behavior:

  • all books appear.

Select Want to Read.

Expected behavior:

  • only matching books appear;
  • nonmatching books remain stored;
  • the total list is not modified.

Repeat for Reading and Finished.

Then switch back to All.

All books should return.

Test Filtering After Other Actions

Keep one filter active and add a new book.

For example:

  1. Select Reading.
  2. Add a Finished book.

Expected behavior depends on the chosen design, but it should be consistent.

A common expected result is:

  • the new book is stored;
  • it does not appear under the Reading filter;
  • it appears when Finished or All is selected.

Now remove the final visible book while a filter is active.

Expected behavior:

  • the book disappears;
  • a filtered empty-state message appears;
  • books belonging to other statuses remain stored;
  • switching to All shows the remaining books.

These interaction tests often reveal bugs that single-feature tests miss.

Step 5: Test Book Removal

Add at least three books.

Remove the middle item.

Expected behavior:

  • only the selected book disappears;
  • the other two remain;
  • their data does not change;
  • the list does not become duplicated;
  • the active filter remains correct.

Remove all remaining books.

Expected behavior:

  • the list becomes empty;
  • the empty-state message appears;
  • no broken book card remains;
  • local storage reflects the empty list.

Refresh the page.

The deleted books should not return.

Step 6: Test Local Storage Persistence

Local storage is one of the most important release checks for this application.

Use this sequence:

  1. Add two books.
  2. Assign different statuses.
  3. Refresh the browser.
  4. Confirm both books remain.
  5. Remove one book.
  6. Refresh again.
  7. Confirm the removed book does not return.
  8. Close and reopen the page.
  9. Confirm the remaining book still appears.

Inspect local storage using browser developer tools.

Check:

  • the expected storage key exists;
  • the value contains valid JSON;
  • no unnecessary user data is stored;
  • no API key or secret appears;
  • removed items are actually removed.

Test Missing Storage

Clear the site’s storage and reload.

Expected behavior:

  • the application starts with an empty list;
  • no error blocks the interface;
  • the user can add a new book normally.

Test Invalid Stored Data

During development, you may temporarily replace the stored value with invalid JSON.

For example:

not-valid-json

Reload the application.

Expected behavior:

  • the app does not permanently crash;
  • it recovers to an empty list or another documented safe state;
  • a concise development warning may appear;
  • raw stored user data is not unnecessarily printed.

Restore or clear the test value afterward.

Do not ship deliberately corrupted data.

Step 7: Test Optional API Behavior

When the application includes optional book search, test it separately from manual entry.

The core manual workflow must continue working whether the API succeeds or fails.

Successful Search

Test a normal search term.

Expected behavior:

  • a loading state appears;
  • a limited number of results appears;
  • title and author fields display correctly;
  • selecting a result fills the existing form;
  • the book is not saved automatically;
  • the user can review the values before adding it.

Empty Search

Submit an empty or too-short search.

Expected behavior:

  • no unnecessary network request is sent;
  • the interface explains the minimum input requirement.

No Results

Search for an unlikely string.

Expected behavior:

  • a useful no-results message appears;
  • the application remains usable;
  • manual entry remains available.

Network Failure

Use the browser’s offline mode or temporarily block the request.

Expected behavior:

  • the loading state ends;
  • a clear error message appears;
  • existing form data remains;
  • saved books remain available;
  • manual entry continues to work.

Security Check

Inspect the Network panel.

Confirm:

  • no private key appears in request URLs;
  • no private authorization token appears in browser requests;
  • only necessary query data is sent;
  • requests use HTTPS;
  • the response does not cause unsafe HTML insertion.

A browser-based secret should be treated as publicly visible.

Step 8: Check the Browser Console and Network Panel

Testing the interface alone is not enough.

Open the Console panel and repeat the major workflows.

Look for:

  • uncaught exceptions;
  • undefined variables;
  • failed resource loads;
  • invalid selectors;
  • deprecated behavior warnings;
  • repeated logs;
  • unexpected network errors.

A few development warnings may not break the app, but each should be understood.

Remove logs such as:

console.log(books);
console.log(apiResponse);
console.log("test");

before release unless they serve a deliberate operational purpose.

The Network panel can reveal:

  • missing CSS;
  • missing JavaScript;
  • incorrect image paths;
  • failed API requests;
  • repeated requests;
  • files loaded from a local development URL;
  • unexpectedly large assets.

Step 9: Test Paths and File Names

Static sites often work locally but fail after deployment because of path differences.

Suppose the repository contains:

reading-list-tracker/
├── index.html
├── styles.css
├── app.js
└── assets/
    └── book-icon.svg

Relative references might look like:

<link rel="stylesheet" href="./styles.css">
<script src="./app.js" defer></script>
<img src="./assets/book-icon.svg" alt="">

Be careful with root-relative paths such as:

<script src="/app.js"></script>

A root-relative path may behave differently when the site is hosted under a repository subpath.

For example, a deployed URL may resemble:

https://example.com/reading-list-tracker/

In that environment, /app.js may point to the domain root rather than the project directory.

Relative paths are often easier for a simple static project, but the correct choice depends on the hosting setup.

Check Capitalization

A file named:

Styles.css

is different from:

styles.css

on many hosting systems.

A local environment may appear more forgiving than production.

Confirm that file names and references use identical capitalization.

Step 10: Test Responsive Layout

The application should remain usable at different viewport widths.

You do not need dozens of devices.

Check at least:

  • a typical desktop width;
  • a tablet-like width;
  • a narrow phone-like width.

At narrow widths, confirm:

  • form controls fit within the screen;
  • text does not overlap;
  • buttons remain visible;
  • book titles wrap;
  • filter controls remain usable;
  • horizontal scrolling is not required for the main interface;
  • focus outlines are not cut off;
  • empty and error messages remain readable.

Use the responsive design mode in browser developer tools, but also resize a normal browser window.

A device preview is useful, not perfect.

Step 11: Perform a Basic Accessibility Review

A beginner release does not require claiming full accessibility compliance.

It should still include basic usable patterns.

Check:

  • every form input has a visible label;
  • labels are associated with the correct controls;
  • buttons have understandable text;
  • keyboard users can reach interactive elements;
  • focus states are visible;
  • headings follow a logical structure;
  • status is not communicated only through color;
  • validation messages are understandable;
  • text contrast appears readable;
  • images have appropriate alternative text;
  • decorative images use empty alternative text when appropriate.

Keyboard Test

Use only the keyboard.

Try:

  • Tab;
  • Shift+Tab;
  • Enter;
  • Space;
  • arrow keys inside select controls.

Confirm that you can:

  • reach the form;
  • enter data;
  • select a status;
  • submit a book;
  • change filters;
  • remove a book;
  • use optional search results.

A visible application that cannot be operated with a keyboard has an important usability gap.

Step 12: Review the Repository Before Deployment

Run:

git status

Inspect all modified and untracked files.

Look for unwanted artifacts such as:

.env
.env.local
debug.log
test-output.txt
api-response.json
notes-private.txt
.DS_Store
Thumbs.db

Check the full diff:

git diff

Review staged changes separately:

git diff --staged

Search for Secrets

Inspect the project for:

  • API keys;
  • passwords;
  • tokens;
  • authorization headers;
  • private URLs;
  • customer data;
  • personal notes;
  • internal file paths.

A simple text search can help:

grep -RniE "api[_-]?key|secret|token|password|authorization|bearer" .

This command may find harmless examples or documentation, so review every result.

It does not prove the repository is secret-free.

Review .gitignore

A simple static project may ignore files such as:

.env
.env.local
.DS_Store
Thumbs.db

Only ignore files that are genuinely local or sensitive.

Do not use .gitignore to hide source files required for deployment.

Step 13: Confirm the Deployment Contents

A plain HTML, CSS, and JavaScript application may not require a build step.

The deployment contents may be:

index.html
styles.css
app.js
assets/
README.md

The README does not affect the website, though it may remain in the repository.

Confirm that index.html is in the location expected by the hosting provider.

If the project uses a build tool, the provider may need the generated output directory rather than the source directory.

Examples of possible output directory names include:

dist
build
public

Do not guess.

Check the project configuration and current hosting documentation.

For this series, the simplest deployment path is a static site with no required server process.

Step 14: Create a Release Commit

After all required fixes are complete, run the full test checklist again.

Then stage the intended files:

git add index.html styles.css app.js README.md

Review:

git diff --staged

Create a release-focused commit:

git commit -m "Prepare reading list tracker for deployment"

You may also create a version tag when it helps your workflow:

git tag -a v1.0.0 -m "First public release"

Push the commit and tag when appropriate:

git push
git push --tags

A tag is optional for a small beginner project, but it creates a clear reference to the published version.

Before using version numbers, keep the scheme simple and consistent.

Step 15: Choose a Static Hosting Approach

The reading list tracker can be deployed to a static hosting service because it does not require a continuously running backend.

Common hosting approaches include:

  • hosting directly from a Git repository;
  • uploading static files;
  • deploying through a connected build pipeline;
  • publishing through a static-site service.

The exact provider is less important than the release process.

A typical repository-based deployment looks like:

Git repository
→ Hosting provider reads selected branch
→ Provider publishes static files
→ Public URL becomes available

Before enabling deployment, confirm:

  • which branch is published;
  • which folder is published;
  • whether a build command is required;
  • whether environment variables are configured;
  • whether the project uses a custom domain;
  • whether deployments happen automatically after each push.

For this project, a no-build static deployment is the simplest option.

Example Deployment Flow

A platform-neutral process may look like this.

1. Push the Verified Commit

git push origin main

2. Connect the Repository

In the hosting provider’s dashboard:

  • select the repository;
  • authorize only the required access;
  • select the intended branch;
  • choose the directory containing index.html;
  • leave the build command empty when no build is needed;
  • review the deployment settings.

Exact interface wording varies.

3. Start the Deployment

The provider copies or builds the project and assigns a public URL.

4. Review the Deployment Log

Look for:

  • missing files;
  • path errors;
  • permission failures;
  • build failures;
  • environment-variable warnings;
  • unsupported runtime settings.

Do not ignore a warning simply because the provider reports a successful deployment.

5. Open the Public URL

Do not assume the live application matches the local one.

Begin the post-deployment test process.

Step 16: Test the Live Application

Repeat the critical local tests using the public URL.

At minimum, verify:

  • the page loads;
  • CSS loads;
  • JavaScript runs;
  • the browser console has no unexpected errors;
  • a book can be added;
  • invalid titles are rejected;
  • filters work;
  • removal works;
  • local storage survives refresh;
  • empty states work;
  • responsive layout remains usable;
  • optional API behavior works or fails gracefully.

Use a Fresh Browser Context

Test in:

  • a private browsing window;
  • another browser;
  • another device when available.

A normal browser may contain cached files or existing local storage from development.

A fresh context helps reveal:

  • missing initialization;
  • path errors;
  • cache-related behavior;
  • assumptions about existing data.

Step 17: Understand Local Storage After Deployment

Local storage is tied to the site’s origin.

That means data saved under a local development address does not automatically appear on the deployed site.

For example:

Local:
http://127.0.0.1:5500

Deployed:
https://example-host.com/reading-list-tracker

These are different origins.

The live application will begin with its own empty local storage.

This is expected behavior, not data loss.

Also remember:

  • another browser has separate storage;
  • another device has separate storage;
  • private browsing may delete storage after the session;
  • clearing site data removes the list;
  • local storage is not cloud synchronization.

The app should not claim that data is backed up or shared across devices.

Step 18: Verify Security-Related Deployment Details

Inspect the live page and network requests.

Confirm:

  • HTTPS is active;
  • no secret appears in source files;
  • no secret appears in request URLs;
  • no private environment variable appears in the client bundle;
  • no development-only endpoint is used;
  • external resources load from expected locations;
  • no mixed HTTP content is requested;
  • error messages do not expose credentials or internal paths.

View the deployed JavaScript source.

Anything included in the browser bundle should be considered public.

When an API requires a private key, that key must remain in a protected server-side environment.

Step 19: Check Metadata and Basic Presentation

Before sharing the application, review the HTML document metadata.

At minimum:

<title>Personal Reading List Tracker</title>
<meta
  name="description"
  content="A simple browser-based app for saving books and tracking reading status."
>
<meta name="viewport" content="width=device-width, initial-scale=1">

Confirm:

  • the browser tab title is meaningful;
  • the page has one clear main heading;
  • the description reflects the application;
  • the favicon does not point to a missing file;
  • visible text has no temporary placeholder;
  • buttons do not say Test, Click Here, or TODO;
  • sample books are not included unintentionally.

Metadata does not repair a weak application, but it helps the published result feel complete.

Step 20: Test Refresh and Direct Navigation

Static deployment paths can behave differently after refresh.

For a one-page application using only index.html, refresh should normally work.

If the project later adds client-side routes such as:

/books
/settings

the hosting provider may need additional fallback configuration.

For the current reading list tracker, keep the routing simple.

Test:

  • opening the root URL;
  • refreshing;
  • opening the URL in a new tab;
  • sharing the URL;
  • loading it with no prior site data.

Step 21: Document the Live Version

Update the README with:

  • project description;
  • feature list;
  • local usage instructions;
  • deployment URL;
  • storage limitations;
  • optional API setup;
  • test checklist;
  • known limitations.

For example:

## Data Storage

The app stores books in the browser's localStorage.

Data is specific to the current browser and site address. It is not synchronized between devices and may be removed when site data is cleared.

This prevents users from assuming the project includes accounts, backups, or cloud storage.

Record Known Limitations

Useful limitations may include:

  • no user accounts;
  • no cloud synchronization;
  • no backup;
  • no editing;
  • local storage only;
  • optional API search may be unavailable;
  • data remains on one browser and origin.

Honest limitations make a small application easier to trust.

Step 22: Create a Post-Deployment Checklist

A release is not complete immediately after the hosting provider reports success.

Use a checklist like this:

[ ] Public URL loads
[ ] HTTPS works
[ ] CSS loads
[ ] JavaScript runs
[ ] Console has no unexpected errors
[ ] Add Book works
[ ] Validation works
[ ] Filtering works
[ ] Removal works
[ ] Refresh persistence works
[ ] Empty states work
[ ] Mobile layout is usable
[ ] Keyboard navigation works
[ ] No secret is visible
[ ] Optional API fails gracefully
[ ] README contains the live URL

Record the date and commit hash associated with the deployment.

For example:

Deployment:
v1.0.0

Commit:
8c3f9d1

Verified:
[publication date]

This makes future debugging more precise.

Step 23: Know When to Roll Back

A deployed version should be rolled back or replaced when it contains a serious problem.

Examples include:

  • the application does not load;
  • user data is deleted incorrectly;
  • private credentials are exposed;
  • a deployment publishes confidential files;
  • core features fail consistently;
  • an API integration creates uncontrolled requests;
  • the live version differs substantially from the tested commit.

A visual spacing issue may be fixed in the next normal update.

An exposed credential requires immediate action.

Rollback Approaches

Depending on the hosting provider and workflow, recovery may involve:

  • redeploying the previous verified commit;
  • reverting the problematic commit;
  • restoring the last known good branch;
  • selecting a previous deployment;
  • disabling the optional feature;
  • temporarily removing the public deployment.

The exact dashboard controls vary.

Git gives you a provider-independent recovery path.

For a bad commit:

git revert <commit-hash>
git push

The hosting provider can then deploy the new revert commit.

Step 24: Do Not Fix Production with Unreviewed Edits

A public bug can create pressure to move quickly.

Avoid this sequence:

See bug
→ Ask AI to fix everything
→ Push without testing
→ Create another bug

Use a smaller emergency process:

Reproduce live bug
→ Confirm local reproduction
→ Identify relevant commit
→ Create focused fix
→ Test locally
→ Review diff
→ Commit
→ Deploy
→ Verify live

The urgency of a bug does not remove the need for evidence.

It makes a focused process more important.

Example Release Test Matrix

The following matrix summarizes useful checks for the reading list tracker.

AreaTestExpected Result
Initial stateOpen with no storageEmpty state appears
Add bookValid title and authorOne book appears
ValidationEmpty titleBook is rejected
ValidationSpaces-only titleBook is rejected
AuthorEmpty authorBook is accepted
FilteringSelect each statusOnly matching books appear
RemovalRemove one of severalOnly selected book disappears
PersistenceRefresh after addingBooks remain
PersistenceRefresh after removalRemoved book stays removed
Storage failureInvalid JSONApp recovers safely
API searchSuccessful requestResults appear
API failureOffline requestManual entry remains usable
ResponsiveNarrow viewportControls remain usable
KeyboardTab through interfaceAll controls are reachable
DeploymentFresh browserApp initializes correctly
SecurityInspect network and filesNo private secret is exposed

This matrix can be adapted as the project grows.

Common Testing Mistakes

Testing Only One Successful Example

A single working book does not prove validation, filtering, removal, or persistence.

Testing While the Code Keeps Changing

Freeze the release candidate before final testing.

Trusting AI-Generated Test Claims

Run the application and verify behavior yourself.

Ignoring Browser Errors

The interface may look correct while JavaScript reports problems.

Forgetting Feature Interactions

Filtering may work until a book is removed or added.

Testing Only with Existing Storage

A fresh user starts with no local data.

Forgetting the Live Version

Local success does not prove deployed success.

Treating Local Storage as a Cloud Database

It does not synchronize between browsers or devices.

Publishing Debug Files

Untracked logs and response files may contain data you did not intend to share.

Common Deployment Mistakes

Deploying the Wrong Branch

Confirm which branch and commit the host publishes.

Publishing the Wrong Folder

The host must find the correct index.html or generated output directory.

Using Incorrect Paths

Root-relative paths may fail under a repository subdirectory.

Exposing Environment Variables

Client-side variables may become public.

Assuming a Successful Build Means a Working App

Open and test the public URL.

Forgetting HTTPS or Mixed Content

Secure pages may block insecure resources.

Pushing Unrelated Changes

The release commit should have one clear purpose.

Having No Recovery Plan

Know which commit represents the last verified release.

A Practical Release Workflow

Use this sequence for the first public version:

1. Stop adding features.
2. Confirm the project brief and release scope.
3. Start from a clean Git state.
4. Run the complete local test checklist.
5. Fix one verified issue at a time.
6. Repeat affected tests.
7. Review responsive and keyboard behavior.
8. Inspect console and network activity.
9. Review storage and optional API behavior.
10. Search the repository for secrets and artifacts.
11. Review every changed file.
12. Create a release commit.
13. Push the verified commit.
14. Deploy the correct branch and folder.
15. Review deployment logs.
16. Test the live URL in a fresh browser.
17. Record the deployed commit.
18. Revert or redeploy if a serious issue appears.

This process is intentionally repetitive.

Release confidence comes from checking the same important assumptions at several boundaries.

Practical Advice from Development Work

In real software delivery, deployment problems are often caused by small assumptions rather than dramatic coding failures.

A file path works locally but not on the host.

A setting exists on one machine but not in production.

A browser contains old local storage that hides an initialization bug.

A successful API response receives more testing than the failure path.

AI-generated applications are especially vulnerable to these assumptions because the code can be produced before the developer fully understands the deployment environment.

The most useful release habit is to separate evidence into three stages:

Local evidence
→ Repository evidence
→ Live evidence

Local evidence shows that the feature works on your computer.

Repository evidence shows that the correct files and configuration are committed.

Live evidence shows that the deployed application behaves correctly in its public environment.

All three matter.

A Reusable Pre-Deployment Checklist

Scope

  • The release features are defined.
  • New feature work has stopped.
  • Optional ideas are recorded separately.
  • The project brief matches the implementation.

Behavior

  • Core workflow passes.
  • Invalid input is handled.
  • Empty states work.
  • Filters work.
  • Removal works.
  • Persistence works.
  • Related features work together.

Interface

  • Desktop layout is usable.
  • Narrow layout is usable.
  • Keyboard navigation works.
  • Labels and buttons are understandable.
  • Focus styles are visible.
  • Errors are readable.

Technical Review

  • Console has no unexplained errors.
  • Network requests are expected.
  • File paths are correct.
  • File-name capitalization matches.
  • External data is handled safely.
  • Optional API failure does not break the app.

Repository

  • Working tree is understood.
  • Untracked files are reviewed.
  • No environment file is committed.
  • No credential is visible.
  • Debug logs are removed.
  • Staged diff contains only release work.
  • Release commit is meaningful.

Deployment

  • Correct branch is selected.
  • Correct output folder is selected.
  • Build settings are verified.
  • Environment settings are reviewed.
  • Deployment log is checked.
  • Public URL is recorded.

Post-Deployment

  • Fresh browser test passes.
  • Core workflow passes live.
  • Local storage works on the deployed origin.
  • Console remains clean.
  • HTTPS is active.
  • No secret appears in client files.
  • Deployed commit is documented.
  • Rollback path is known.

Conclusion

Testing and deployment are not the final button presses after vibe coding.

They are development stages that require their own evidence.

For the Personal Reading List Tracker, a responsible release includes testing the complete user workflow, invalid inputs, filtering, removal, local storage, optional API failure, responsive layout, keyboard navigation, repository contents, and deployed behavior.

The core release sequence is:

Freeze
→ Test
→ Review
→ Commit
→ Deploy
→ Verify
→ Recover when necessary

A live URL is valuable only when you know which version it contains and how that version was tested.

The final article in this series will step back from the project and examine the limits and future of vibe coding. We will look at where AI-assisted development provides real value, where it creates risk, which skills remain essential, and how beginners can continue improving after completing their first application.

Frequently Asked Questions

Do I need automated tests before deploying my first app?

Not necessarily for a small learning project, but you do need a repeatable verification process.

Manual testing can be sufficient for a simple first release when the workflows and results are documented clearly. Automated tests become more valuable as the application and number of regressions grow.

Can I deploy directly after an AI assistant says the project is ready?

No.

Treat that statement as a suggestion. Review the repository, run the application, test the acceptance criteria, inspect the browser console, and verify the deployed version yourself.

Why is my local reading list missing from the deployed site?

Local storage belongs to a specific browser origin.

Data saved under a local development address does not automatically transfer to a deployed domain. The public version begins with its own separate storage.

Comments

Popular posts from this blog

Claude Code Multi-Agent Setup for Beginners: Models, Roles, and Your First Project

The Limits and Future of Vibe Coding