Date de baja de todos los canales de golpe y conserva los que elijas. Gratis, en tu navegador, sin dar tu contraseña a nadie.
// Responsive Muse · Unsubscribe From All YouTube Channels · v1.1 · 2026-10-22
// Unsubscribes you from every channel, except the ones you list in KEEP.
// Runs only on youtube.com/feed/channels. It counts first and asks before changing anything,
// then clicks the same Unsubscribe button and confirmation you would. It makes no network
// requests of its own and never reads cookies, passwords or tokens.
(async () => {
const TOOL = 'Anular todas las suscripciones';
const KEEP = []; // channels to keep, by name or @handle, e.g. ['@mkbhd', 'Veritasium']
const LIMIT = 0; // stop after this many channels (0 = no limit)
const DELAY = 900; // pause between actions, in milliseconds
if (location.hostname !== 'www.youtube.com' || location.pathname !== '/feed/channels') {
alert('Abre primero tus suscripciones (con tu sesión iniciada):\nhttps://www.youtube.com/feed/channels');
return;
}
// A small box on the page shows progress and asks before changing anything,
// so you never need to read or edit the console.
const many = (n, word) => `${n} ${n === 1 ? word : ({ canal: 'canales', 'canción': 'canciones', 'publicación': 'publicaciones', 'elemento guardado': 'elementos guardados', lugar: 'lugares' })[word] || word + 's'}`; // 1 vídeo, 2 vídeos
const panel = (() => {
const box = document.createElement('div');
box.style.cssText = 'display:block!important;position:fixed;right:16px;bottom:16px;z-index:2147483647;width:340px;max-width:calc(100vw - 32px);' +
'background:#111318;color:#e6e8ee;font:14px/1.5 system-ui,sans-serif;border-radius:12px;padding:16px;' +
'box-shadow:0 8px 30px rgba(0,0,0,.4);text-align:left';
const head = document.createElement('strong');
head.textContent = TOOL;
const msg = document.createElement('p');
msg.style.cssText = 'margin:8px 0 12px;white-space:pre-line';
const row = document.createElement('div');
row.style.cssText = 'display:flex;flex-wrap:wrap;gap:8px;justify-content:flex-end';
box.append(head, msg, row);
document.body.append(box);
const button = (label, primary, onClick) => {
const b = document.createElement('button');
b.textContent = label;
b.style.cssText = 'font:600 14px system-ui,sans-serif;padding:8px 14px;border-radius:8px;cursor:pointer;' +
(primary ? 'background:#0f766e;color:#fff;border:1px solid #0f766e' : 'background:none;color:#e6e8ee;border:1px solid #3a3f4b');
b.onclick = onClick;
row.append(b);
};
return {
text(t) { msg.textContent = t; },
ask(t, yes) {
msg.textContent = t;
row.replaceChildren();
return new Promise(r => {
button('Cancelar', false, () => { row.replaceChildren(); r(false); });
button(yes, true, () => { row.replaceChildren(); r(true); });
});
},
stoppable(onStop) { row.replaceChildren(); button('Parar', false, onStop); },
actions(t, list) {
msg.textContent = t;
row.replaceChildren();
list.forEach(([label, primary, run]) => button(label, primary, run));
},
finish(t) { this.actions(t, [['Cerrar', true, () => box.remove()]]); },
close() { box.remove(); },
};
})();
const sleep = ms => new Promise(r => setTimeout(r, ms));
// Wait until something shows up on screen (menus can take a moment to open)
const visible = e => e.getClientRects().length > 0;
const waitFor = async (find, ms = 4000) => {
for (let t = 0; t < ms; t += 150) {
const hit = find();
if (hit) return hit;
await sleep(150);
}
return null;
};
const keep = new Set(KEEP.map(k => k.trim().toLowerCase()));
const text = (el, sel) => (el.querySelector(sel)?.textContent || '').trim();
const kept = el => keep.has(text(el, '#channel-title #text').toLowerCase()) || keep.has(text(el, '#subscribers').toLowerCase());
// The button that unsubscribes is labelled "Unsubscribe from <channel>" (also in other languages)
const UNSUB = /^(unsubscribe|cancelar (la )?suscripción|anular suscripción|cancelar inscrição|se désabonner|désabonner|abo beenden|annulla iscrizione)/i;
const unsubButton = el => [...el.querySelectorAll('#subscribe-button button[aria-label]')]
.find(b => UNSUB.test(b.getAttribute('aria-label')));
const done = new Set(); // each channel is handled once, even if YouTube is slow to update the button
const channelId = el => el.data?.channelId || text(el, '#channel-title #text');
const subscribed = () => [...document.querySelectorAll('ytd-channel-renderer')]
.filter(el => !kept(el) && !done.has(channelId(el)) && unsubButton(el));
// 1. Load the whole list
let last = -1, idle = 0;
while (idle < 3) {
window.scrollTo(0, document.documentElement.scrollHeight);
await sleep(1200);
const n = document.querySelectorAll('ytd-channel-renderer').length;
idle = n === last ? idle + 1 : 0;
last = n;
panel.text(`Cargando tus suscripciones… ${n} canales`);
}
const total = LIMIT ? Math.min(LIMIT, subscribed().length) : subscribed().length;
if (!total) {
panel.finish(keep.size ? 'Solo quedan los canales que elegiste conservar.' : 'No estás suscrito a ningún canal.');
return 0;
}
// 2. Ask
const kept_ = keep.size ? `\nSe conservan: ${KEEP.join(', ')}` : '';
if (!await panel.ask(`¿Anular la suscripción a ${many(total, 'canal')}?${kept_}\nNo se puede deshacer.`, `Anular ${total}`)) {
panel.finish('Cancelado. No se ha cambiado nada.');
return 0;
}
// 3. Unsubscribe one by one: the button, then YouTube's confirmation dialog
let stop = false;
panel.stoppable(() => { stop = true; });
let count = 0;
while (!stop && count < total) {
const el = subscribed()[0];
if (!el) break;
done.add(channelId(el));
const name = text(el, '#channel-title #text');
el.scrollIntoView({ block: 'center' });
unsubButton(el).click();
const dialog = await waitFor(() => [...document.querySelectorAll('yt-confirm-dialog-renderer')].find(visible));
const confirm = dialog && [...dialog.querySelectorAll('button')].pop();
if (!confirm) {
panel.finish(`Anuladas ${count}; después YouTube no mostró la confirmación para ${name}.\nPuede que YouTube haya cambiado su diseño: avísanos en responsive-muse.com.`);
return count;
}
confirm.click();
// Wait for the dialog to close, so the next channel doesn't reuse it
await waitFor(() => !visible(dialog) || null);
count++;
panel.text(`Unsubscribing… ${count} of ${total}\n${name}`);
await sleep(DELAY);
}
panel.finish(`${stop ? 'Parado' : 'Hecho'}: anuladas ${count} de ${many(total, 'canal')}.\nRecarga la página para ver el resultado.`);
return count;
})();
🛡️ ¿Chrome te dice «No pegues código…»? Es normal. Escribe allow pasting en la consola (o permitir pegar si tu Chrome está en español), pulsa Intro y vuelve a pegar. Solo hace falta una vez.
¿Por qué avisa Chrome?
Chrome lo muestra la primera vez que alguien pega algo en la consola, para proteger de estafas en las que te piden pegar código desconocido. Hace bien en avisar, y por eso este script está entero a la vista: 133 líneas comentadas que no envían nada a ningún sitio ni tocan tus contraseñas o cookies. Por qué es seguro.
¿Prefieres no usar la consola? Arrastra el botón Anular todas las suscripciones a tu barra de marcadores y haz clic en él estando en www.youtube.com. Así no sale el aviso.
Marcador: arrastra el botón del medio a tu barra de marcadores, abre www.youtube.com y pulsa el marcador. Ejecuta el mismo script con las opciones de arriba.
- No envía nada a ningún sitio. Sin fetch, XHR ni scripts externos. La única actividad de red es la de www.youtube.com cargando tu lista.
- No toca tu sesión. No lee cookies, contraseñas, tokens ni el almacenamiento del navegador.
- Solo funciona en www.youtube.com. En cualquier otra web se detiene antes de hacer nada.
- Corto y legible. 133 líneas comentadas, sin minificar ni ofuscar.
- Pregunta antes de cambiar nada. Un recuadro en la página muestra lo que ha encontrado y espera tu OK. Puedes pararlo cuando quieras.
- El mismo código para todos. SHA-256 de la versión por defecto:
1a9c7be5e17485f6…
Compruébalo tú mismo en 30 segundos
- Léelo: todas las líneas están arriba, con comentarios.
- Busca en el código
fetch,XMLHttpRequest,cookie,localStorageoeval. No aparece ninguna. - Abre la pestaña Red (Network) antes de ejecutarlo: solo verás peticiones a www.youtube.com.
Ten en cuenta: esto no se puede deshacer en bloque. El script siempre muestra cuántos hay y pregunta antes de empezar. Deja la pestaña abierta hasta que el recuadro diga «Hecho».
Cómo usarlo
- Abre tus suscripciones con tu sesión iniciada.
- Abre la consola: F12 o Ctrl+Mayús+J (Cmd+Opción+J en Mac). Si Chrome te lo pide, escribe
permitir pegar(oallow pastingsi lo tienes en inglés) y pulsa Enter. - Elige las opciones, copia el script, pégalo en la consola y pulsa Enter. Un recuadro te dice cuántos ha encontrado y espera tu confirmación antes de empezar. Puedes pulsar Parar cuando quieras.
Antes de empezar
Si quieres guardar la lista, expórtala primero con el exportador de suscripciones. YouTube no avisa a los canales cuando te das de baja.
Preguntas frecuentes
¿Se enteran los canales de que me he dado de baja?
No. YouTube no avisa a los creadores cuando alguien anula su suscripción.
¿Puedo conservar algunos canales?
Sí. Escribe sus nombres o @usuarios en «Canales que conservar» y el script se los salta.
¿Exporto antes mis suscripciones?
Es buena idea. Usa el exportador de suscripciones para guardar una copia en CSV u OPML antes de empezar.
