readme.md

    execa logo

    Coverage Status

    Process execution for humans





    Execa runs commands in your script, application or library. Unlike shells, it is optimized for programmatic usage. Built on top of the child_process core module.


    One of the maintainers @ehmicky is looking for a remote full-time position. Specialized in Node.js back-ends and CLIs, he led Netlify Build, Plugins and Configuration for 2.5 years. Feel free to contact him on his website or on LinkedIn!


    Features

    Install

    npm install execa
    

    Documentation

    Execution:

    Input/output:

    Advanced usage:

    Examples

    Execution

    Simple syntax

    import {execa} from 'execa';
    
    const {stdout} = await execa`npm run build`;
    // Print command's output
    console.log(stdout);
    

    Script

    import {$} from 'execa';
    
    const {stdout: name} = await $`cat package.json`.pipe`grep name`;
    console.log(name);
    
    const branch = await $`git branch --show-current`;
    await $`dep deploy --branch=${branch}`;
    
    await Promise.all([
    	$`sleep 1`,
    	$`sleep 2`,
    	$`sleep 3`,
    ]);
    
    const directoryName = 'foo bar';
    await $`mkdir /tmp/${directoryName}`;
    

    Local binaries

    $ npm install -D eslint
    
    await execa({preferLocal: true})`eslint`;
    

    Pipe multiple subprocesses

    const {stdout, pipedFrom} = await execa`npm run build`
    	.pipe`sort`
    	.pipe`head -n 2`;
    
    // Output of `npm run build | sort | head -n 2`
    console.log(stdout);
    // Output of `npm run build | sort`
    console.log(pipedFrom[0].stdout);
    // Output of `npm run build`
    console.log(pipedFrom[0].pipedFrom[0].stdout);
    

    Input/output

    Interleaved output

    const {all} = await execa({all: true})`npm run build`;
    // stdout + stderr, interleaved
    console.log(all);
    

    Programmatic + terminal output

    const {stdout} = await execa({stdout: ['pipe', 'inherit']})`npm run build`;
    // stdout is also printed to the terminal
    console.log(stdout);
    

    Simple input

    const {stdout} = await execa({input: getInputString()})`sort`;
    console.log(stdout);
    

    File input

    // Similar to: npm run build < input.txt
    await execa({stdin: {file: 'input.txt'}})`npm run build`;
    

    File output

    // Similar to: npm run build > output.txt
    await execa({stdout: {file: 'output.txt'}})`npm run build`;
    

    Split into text lines

    const {stdout} = await execa({lines: true})`npm run build`;
    // Print first 10 lines
    console.log(stdout.slice(0, 10).join('\n'));
    

    Streaming

    Iterate over text lines

    for await (const line of execa`npm run build`) {
    	if (line.includes('WARN')) {
    		console.warn(line);
    	}
    }
    

    Transform/filter output

    let count = 0;
    
    // Filter out secret lines, then prepend the line number
    const transform = function * (line) {
    	if (!line.includes('secret')) {
    		yield `[${count++}] ${line}`;
    	}
    };
    
    await execa({stdout: transform})`npm run build`;
    

    Web streams

    const response = await fetch('https://example.com');
    await execa({stdin: response.body})`sort`;
    

    Convert to Duplex stream

    import {execa} from 'execa';
    import {pipeline} from 'node:stream/promises';
    import {createReadStream, createWriteStream} from 'node:fs';
    
    await pipeline(
    	createReadStream('./input.txt'),
    	execa`node ./transform.js`.duplex(),
    	createWriteStream('./output.txt'),
    );
    

    IPC

    Exchange messages

    // parent.js
    import {execaNode} from 'execa';
    
    const subprocess = execaNode`child.js`;
    const message = await subprocess.exchangeMessage('Hello from parent');
    console.log(message); // 'Hello from child'
    
    // child.js
    import {getOneMessage, sendMessage} from 'execa';
    
    const message = await getOneMessage(); // 'Hello from parent'
    const newMessage = message.replace('parent', 'child'); // 'Hello from child'
    await sendMessage(newMessage);
    

    Any input type

    // main.js
    import {execaNode} from 'execa';
    
    const ipcInput = [
    	{task: 'lint', ignore: /test\.js/},
    	{task: 'copy', files: new Set(['main.js', 'index.js']),
    }];
    await execaNode({ipcInput})`build.js`;
    
    // build.js
    import {getOneMessage} from 'execa';
    
    const ipcInput = await getOneMessage();
    

    Any output type

    // main.js
    import {execaNode} from 'execa';
    
    const {ipcOutput} = await execaNode`build.js`;
    console.log(ipcOutput[0]); // {kind: 'start', timestamp: date}
    console.log(ipcOutput[1]); // {kind: 'stop', timestamp: date}
    
    // build.js
    import {sendMessage} from 'execa';
    
    await sendMessage({kind: 'start', timestamp: new Date()});
    await runBuild();
    await sendMessage({kind: 'stop', timestamp: new Date()});
    

    Debugging

    Detailed error

    import {execa, ExecaError} from 'execa';
    
    try {
    	await execa`unknown command`;
    } catch (error) {
    	if (error instanceof ExecaError) {
    		console.log(error);
    	}
    	/*
    	ExecaError: Command failed with ENOENT: unknown command
    	spawn unknown ENOENT
    			at ...
    			at ... {
    		shortMessage: 'Command failed with ENOENT: unknown command\nspawn unknown ENOENT',
    		originalMessage: 'spawn unknown ENOENT',
    		command: 'unknown command',
    		escapedCommand: 'unknown command',
    		cwd: '/path/to/cwd',
    		durationMs: 28.217566,
    		failed: true,
    		timedOut: false,
    		isCanceled: false,
    		isTerminated: false,
    		isMaxBuffer: false,
    		code: 'ENOENT',
    		stdout: '',
    		stderr: '',
    		stdio: [undefined, '', ''],
    		pipedFrom: []
    		[cause]: Error: spawn unknown ENOENT
    				at ...
    				at ... {
    			errno: -2,
    			code: 'ENOENT',
    			syscall: 'spawn unknown',
    			path: 'unknown',
    			spawnargs: [ 'command' ]
    		}
    	}
    	*/
    }
    

    Verbose mode

    await execa`npm run build`;
    await execa`npm run test`;
    

    execa verbose output

    Related

    Maintainers

    Описание

    Process execution for humans

    Конвейеры
    0 успешных
    0 с ошибкой