US WARN layoff notices › Watch your employers
Type the companies you care about. This page checks them against every US WARN Act layoff notice filed in the last 180 days and shows you the matches. No account, no email address, no checkout — the matching runs inside your browser and your list is never sent anywhere.
Counted from the free dataset at build time. Latest notice date in the file: 2026-09-22. The whole archive is 61,428 notices back to 1988.
Case-insensitive, and a name matches on whole words, so Boeing finds “Boeing Commercial Airplanes” while Ford does not drag in Stanford, Medford or Rockford — which is what a plain text search of the CSV does. This is the same matcher the paid alerts run.
That is the honest limit of a browser-side tool. After you press Show my matches you can download an .opml file holding one RSS feed per employer you typed — free, no account, no email address — and your reader checks them for you every morning.
| This page (free) | WARN Watch ($49/year) | |
|---|---|---|
| Checks your list | when you open it, or when your feed reader polls the .opml | every daily refresh, automatically |
| Tells you | on screen, or in your RSS reader | it comes to you: private alert page + RSS + calendar (.ics) + optional Slack/Discord/Teams |
| How many terms | as many as you like | up to 500 terms plus whole states |
| History per match | notice count & first year | full filing record — every state, every prior notice, worker totals |
| Separation reminder | — | again 14 days before the layoff date |
One-off, no auto-renew, 14-day refund. See a real alert page first — no email needed to look.
The file behind this page is watch-recent.json, rebuilt
by the same daily pipeline that publishes the
free dataset
and the source repo. Notices come
from official WARN Act filings by 48 state agencies, normalized into one schema; 44 of those
states have at least one notice inside the 180-day window. Your watchlist is
stored in this browser only (localStorage) and mirrored into this page's own URL, so you can bookmark
it or send it to a colleague — it never touches a server of ours. Any page on this site can
open the tool pre-filled: watch-now.html?q=Boeing|Kaiser or ?s=CA,TX.
What is counted: three 1×1 images on the public jsDelivr CDN — one when this page opens, one if it opened pre-filled from a link, one the first time a non-empty list is matched. That is a daily total per file, published openly by jsDelivr; no cookie, no ID, and never the names you typed.
Nothing here is legal or financial advice, and a WARN notice is an employer's filing, not a guarantee that a layoff happened as described. Corrections: open an issue on the source repo.
\n\n'; } function render(w){ var rows=match(w), lastSeen=seen0(); var res=$('results'); if(!w.t.length && !w.s.length){ $('stat').textContent=''; res.innerHTML='
'; return; } if(!USED){USED=true;px('https://cdn.jsdelivr.net/gh/APVentureEngine/warn-act-notices@main/assets/px-tool-used.png');} var fresh=0; rows.forEach(function(r){ if(lastSeen && r[8] && r[8]>lastSeen) fresh++; }); $('stat').innerHTML=''+num(rows.length)+' notice'+(rows.length===1?'':'s')+ ' in the last '+DATA.window_days+' days match your list'+ (fresh?(' · '+num(fresh)+' new since you last looked'):'')+'.'; // c526: the offer, stated on the visitor's OWN list, right under the result. var what=[]; if(w.t.length) what.push(w.t.length===1?'name':num(w.t.length)+' names'); if(w.s.length) what.push(w.s.length===1?'state':num(w.s.length)+' states'); var lst=what.join(' and '), these=((w.t.length+w.s.length)===1?'this ':'these ')+lst; function upsell(n){ var lead = n ? ''+num(n)+(n===1?' notice':' notices')+' matched your '+lst+' today. This page will not look again until you reopen it.' : 'None of your '+lst+' filed a WARN notice in the last '+DATA.window_days+' days. The next one can land tomorrow, and this page will not tell you unless you come back.'; return '
'+lead+'
'+ 'WARN Watch runs this same match after every daily rebuild and sends only what is new to a private alert page, RSS, calendar and Slack — up to 500 names plus whole states.
'+ ''+ 'One-off, no auto-renew, 14-day refund. Your list stays in this browser; you paste it again at checkout.
'; } if(!rows.length){ res.innerHTML='
'+subBlock(rows,w)+upsell(0); } else { var h='
| Notice date | Employer | Where | '+ 'Workers | Type | Effective |
|---|---|---|---|---|---|
| '+esc(r[3])+(isNew?'NEW':'')+' | '+ ''+esc(r[0])+''+hist+' | '+ ''+esc(r[7]||'')+(r[2]?(r[7]?', ':'')+esc(r[2]):'')+' | '+ ''+num(r[5])+' | '+ ''+esc(r[6]||'')+' | '+ ''+esc(r[4]||'')+' |
'+subBlock(rows,w)+upsell(rows.length); } try{localStorage.setItem(LSEEN,DATA.asof)}catch(e){} } // c526: count clicks on the in-result CTA (either button) — one pixel, no ID, nothing about the list. document.getElementById('results').addEventListener('click',function(e){ var a=e.target; while(a && a.tagName!=='A') a=a.parentNode; if(a && a.className && a.className.indexOf('cta')!==-1) px('https://cdn.jsdelivr.net/gh/APVentureEngine/warn-act-notices@main/assets/px-tool-cta.png'); }); // c601: build the .opml in the browser from the visitor's own matches. The list // never leaves the page — same promise as the matcher itself. document.getElementById('results').addEventListener('click',function(e){ var a=e.target; while(a && a.tagName!=='A') a=a.parentNode; if(!a || a.id!=='opml') return; e.preventDefault(); var txt=opmlDoc(); try{ var b=new Blob([txt],{type:'text/x-opml'}), u=URL.createObjectURL(b), d=document.createElement('a'); d.href=u; d.download='warn-watchlist.opml'; document.body.appendChild(d); d.click(); setTimeout(function(){URL.revokeObjectURL(u); document.body.removeChild(d)},0); }catch(err){ window.location.href='data:text/x-opml;charset=utf-8,'+encodeURIComponent(txt); } px('https://cdn.jsdelivr.net/gh/APVentureEngine/warn-act-notices@main/assets/px-tool-opml.png'); }); function boot(){ var w=load(); writeForm(w); if(DEEP){save(w);px('https://cdn.jsdelivr.net/gh/APVentureEngine/warn-act-notices@main/assets/px-tool-deep.png');} $('go').addEventListener('click',function(){var x=readForm();save(x);render(x)}); $('clear').addEventListener('click',function(){ var x={t:[],s:[]}; writeForm(x); save(x); render(x); }); $('stat').textContent='Loading the last '+180+' days of notices\u2026'; var xhr=new XMLHttpRequest(); xhr.open('GET','data/watch-recent.json',true); xhr.onload=function(){ if(xhr.status>=200&&xhr.status<300){ try{DATA=JSON.parse(xhr.responseText)}catch(e){} } if(!DATA){ $('stat').textContent='Could not load the notice file. Reload the page, or use the search page.'; return; } render(w); }; xhr.onerror=function(){$('stat').textContent='Could not load the notice file. Reload the page, or use the search page.'}; xhr.send(); // c601: the employer->feed map, fetched independently. If it never arrives // the page works exactly as it did before; when it does, re-render so the // free subscribe block appears under results already on screen. var fx=new XMLHttpRequest(); fx.open('GET','data/watch-feeds.json',true); fx.onload=function(){ if(fx.status>=200&&fx.status<300){ try{FEEDS=JSON.parse(fx.responseText)}catch(e){} } if(FEEDS&&DATA){ var v=load(); if((v.t||[]).length||(v.s||[]).length) render(v); } }; fx.send(); } if(document.readyState!=='loading') boot(); else document.addEventListener('DOMContentLoaded',boot); })();