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' })[word] || word + 's'}`; // 1 vídeo, 2 vídeos
const panel = (() => {
const box = document.createElement('div');
box.style.cssText = '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;
})();
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:
d8c35a21c2862426…
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.
