# Is “cleos transfer” just a shortcut for “cleos push action eosio.token transfer”?

Here is the documentation for cleos transfer. And here is the one for cleos push action.

It seems that, whenever we want to write:

cleos transfer account11111 account22222 "0.0001 EOS" "memo text"


cleos push action eosio.token transfer '{"from": "account11111", "to": "account22222", "quantity": "0.0001 EOS", "memo": "memo text"}'


So, is there something that cleos transfer does, or can do, that cleos push action can't?

Summary: Functionally, the two are almost identical at the moment, but, conceptually and semantically, transfer accomplishes an implementation-agnostic transfer of tokens, while transferring using push action is a lower-level, implementation-dependent solution that may or may not change in the future.

I think Andres' answer is good, but if you want something more thorough, you can just check the EOSIO code:

In programs/cleos/main.cpp, you can see as follows:

// Transfer subcommand
string con = "eosio.token";
...
send_actions({create_transfer(con,sender, recipient, to_asset(amount), memo)});


where con stands for contract.

Then, if you follow what the create_transfer() function does, you can see it just creates a transaction with an action to eosio.token

return action {
tx_permission.empty() ? vector<chain::permission_level>{{sender,config::active_name}} : get_account_permissions(tx_permission),
contract, "transfer", variant_to_bin( contract, N(transfer), transfer )
};


I guess the transfer subcommand sets some default permissions to the sender, so you can make a transfer without setting the permission explicitly, but at the moment it's just a thin wrapper around the push action subcommand.
However, from a high-level perspective, transfer should guarantee that tokens are transferred between contracts regardless of the underlying implementations of the contracts and the actions that need to be pushed. So, for instance, if the ABI of the token contract changed and you need 2 actions to send, the push action may no longer work as is, while transfer should be updated in the core code to still work. So, even if they're quite similar today, transfer can abstract the transferring implementation, while push is a low-level subcommand that requires knowing the ABI.
Update 19th September: As of v1.3.0, there is an optional "--pay-ram-to-open flag for the cleos transfer command to prepend an eosio.token::open action before the eosio.token::transfer action (#5581)"
It's exactly the same. If you run the cleos transfer command with -d you'll see the transaction that gets sent. It's simply a transaction with a single action to eosio.token::transfer.