
Security News
Axios Supply Chain Attack Reaches OpenAI macOS Signing Pipeline, Forces Certificate Rotation
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.
A simple, lightweight library for peer-to-peer file transfer using WebRTC and Socket.IO. Transfer files directly between browsers without uploading to a server!
A simple, lightweight library for peer-to-peer file transfer using WebRTC and Socket.IO. Transfer files directly between browsers without uploading to a server!
npm i p2p-ft
const express = require('express');
const app = express();
const server = require('http').createServer(app);
const io = require('socket.io')(server, {
cors: {
origin: "*",
methods: ["GET", "POST"]
}
});
// Serve static files (your frontend)
app.use(express.static('public'));
// Handle WebRTC signaling
io.on('connection', (socket) => {
console.log('User connected:', socket.id);
// Forward WebRTC signals between peers
socket.on('signal', (message) => {
io.to(message.to).emit('signal', {
from: socket.id,
data: message.data
});
});
// Notify others when someone disconnects
socket.on('disconnect', () => {
console.log('User disconnected:', socket.id);
});
});
const PORT = process.env.PORT || 3000;
server.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>P2P File Transfer</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 50px auto;
padding: 20px;
}
.section {
margin: 20px 0;
padding: 20px;
border: 1px solid #ddd;
border-radius: 5px;
}
button {
padding: 10px 20px;
margin: 5px;
cursor: pointer;
}
#progress {
width: 100%;
height: 30px;
margin: 10px 0;
}
#status {
padding: 10px;
margin: 10px 0;
background: #f0f0f0;
border-radius: 3px;
}
.peer-list {
margin: 10px 0;
}
.peer-item {
padding: 10px;
margin: 5px 0;
background: #e8f4f8;
border-radius: 3px;
display: flex;
justify-content: space-between;
align-items: center;
}
</style>
</head>
<body>
<h1>P2P File Transfer Demo</h1>
<div class="section">
<h2>Your ID: <span id="myId">Connecting...</span></h2>
<div id="status">Status: Initializing...</div>
</div>
<div class="section">
<h2>Send File</h2>
<input type="file" id="fileInput">
<br><br>
<label>Recipient ID: <input type="text" id="targetId" placeholder="Enter peer ID"></label>
<br><br>
<button onclick="sendFile()">Send File</button>
<br>
<progress id="progress" value="0" max="100"></progress>
<div id="progressText">Ready to send</div>
</div>
<div class="section">
<h2>Received Files</h2>
<div id="receivedFiles">No files received yet</div>
</div>
<script src="/socket.io/socket.io.js"></script>
<script src="/p2p-file-transfer.js"></script>
<script>
// Connect to Socket.IO server
const socket = io('http://localhost:3000');
let fileTransfer;
socket.on('connect', () => {
document.getElementById('myId').textContent = socket.id;
document.getElementById('status').textContent = 'Status: Connected';
// Initialize file transfer
fileTransfer = new P2PFileTransfer(socket, 'signal', {
onProgress: (sent, total) => {
const percent = (sent / total * 100).toFixed(1);
document.getElementById('progress').value = percent;
document.getElementById('progressText').textContent =
`Progress: ${percent}% (${formatBytes(sent)} / ${formatBytes(total)})`;
},
onComplete: (blob, fileName, peerId) => {
// Create download link for received file
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = fileName;
a.textContent = `Download ${fileName} (${formatBytes(blob.size)})`;
a.style.display = 'block';
a.style.margin = '10px 0';
const container = document.getElementById('receivedFiles');
if (container.textContent === 'No files received yet') {
container.textContent = '';
}
container.appendChild(a);
document.getElementById('status').textContent =
`Status: Received ${fileName} from ${peerId}`;
},
onError: (error) => {
console.error('Transfer error:', error);
document.getElementById('status').textContent =
`Status: Error - ${error.message}`;
},
onConnectionStateChange: (peerId, state) => {
console.log(`Connection with ${peerId}: ${state}`);
}
});
});
socket.on('disconnect', () => {
document.getElementById('status').textContent = 'Status: Disconnected';
});
async function sendFile() {
const fileInput = document.getElementById('fileInput');
const targetId = document.getElementById('targetId').value.trim();
if (!fileInput.files.length) {
alert('Please select a file');
return;
}
if (!targetId) {
alert('Please enter recipient ID');
return;
}
const file = fileInput.files[0];
document.getElementById('status').textContent =
`Status: Sending ${file.name} to ${targetId}...`;
try {
await fileTransfer.sendFile(targetId, file);
} catch (error) {
console.error('Send error:', error);
}
}
function formatBytes(bytes) {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return Math.round(bytes / Math.pow(k, i) * 100) / 100 + ' ' + sizes[i];
}
</script>
</body>
</html>
const fileTransfer = new P2PFileTransfer(socket, signalEvent, callbacks);
Parameters:
socket - Socket.IO client instancesignalEvent - Event name for WebRTC signaling (e.g., 'signal')callbacks - Object with callback functions:
onProgress(sent, total) - Called during file transferonComplete(blob, fileName, peerId) - Called when file is receivedonError(error) - Called on errorsonConnectionStateChange(peerId, state) - Called on connection state changessendFile(targetId, file)Send a file to another peer.
await fileTransfer.sendFile('socket-id-here', fileObject);
destroy()Close all connections and cleanup.
fileTransfer.destroy();
MIT
Pull requests are welcome! For major changes, please open an issue first.
If you encounter issues, please file them on GitHub Issues.
FAQs
A simple, lightweight library for peer-to-peer file transfer using WebRTC and Socket.IO. Transfer files directly between browsers without uploading to a server!
We found that p2p-ft demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.

Security News
Open source is under attack because of how much value it creates. It has been the foundation of every major software innovation for the last three decades. This is not the time to walk away from it.

Security News
Socket CEO Feross Aboukhadijeh breaks down how North Korea hijacked Axios and what it means for the future of software supply chain security.