The vote in the National Assembly is a blow to the labour movement, which called three months of rolling strikes over the bill, the longest industrial action in over 30 years on French railways.
Members of the lower house of parliament, where the ruling party has a large majority, adopted the bill by 452 votes for to 80 against and 27 abstentions.
The bill now goes to the Senate for a final vote on Thursday.
Analysts have compared the standoff between the centrist Macron and French railworkers with Margaret Thatcher's showdown with British miners in the 1980s.
It is being closely watched as a sign of Macron's ability to face down France's unions, which have had success in pressuring previous governments to
withdraw, or significantly water down, unpopular reforms.
Train drivers particularly had resisted plans to deny job and pension guarantees to new rail recruits, as well as plans to turn the SNCF into a joint-stock company, which they see as a first step toward privatisation.
The government argues the loss-making SNCF — a bastion of the union movement — needs to cut costs and improve flexibility before the EU passenger rail market opens up to competition.
A poll showed voters largely on board with the changes, unswayed by 30 days of strikes since early April that have caused headaches for millions of travellers on two days out of every five.
The SNCF has estimated the cost of the walkouts at 400 million euros ($470 million).
Labour leaders refused to concede victory on Wednesday, announcing that the strikes would continue as planned until June 28.
“This strike is far from over,” Philippe Martinez of the hardline CGT, France's biggest public sector union, said.
French 'stagnation' over?
But the movement has been showing signs of fatigue, with the number of strikers steadily tapered off in recent weeks. In recent days there has been signs of a growing split between the unions who had put up a united front until now.
The CGT have accused the more militant Sud Rail union of acting in their own interests. The more reformist CFDT union announced it was suspending the strike to allow school pupils to get to the exams, a move which apparently infuriated another union Unsa.
An estimated 12.78 percent of workers walked off the job on Wednesday, down from around 34 percent in April.
Union leaders can claim to have won several concessions, including job guarantees for existing staff if they take a position with a new operator arriving in France.
The government has also pledged take on 35 billion euros of SNCF debt and to not sell off the newly created SNCF shares.
In return, the unions have agreed to begin talks on a new collective labour agreement.
Having refused to back down on the key elements of his plan, Macron may have cleared his path for equally tricky reforms to France's strained pension system and vast public sector.
“For Emmanuel Macron and (Prime Minister) Edouard Philippe, this political victory against a fortress long deemed unassailable (the SNCF) changes everything,” the rightwing Figaro newspaper wrote in an editorial Monday.
“Along with the reform of the labour code, the SNCF reform shows that France is not hopelessly condemned to stagnation,” it added.
By AFP's Clare BYRNE and Joseph SCHMID